Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Globally enable authentication in ServiceStack, except for some requests

Using ServiceStack, I have to selectively enable authentication on services, request DTOs and actions by applying the [Authenticate] attribute on the respective classes/methods.

Is it possible to do the inverse? I.e. globally enable authentication for all services/requests and then selectively disable authentication for some requests (e.g. using something like a [NoAuthentication] attribute on the relevant parts)?

like image 293
M4N Avatar asked Oct 02 '22 16:10

M4N


1 Answers

Create a Request Filter Attribute that sets a flag in the request context saying to skip authentication:

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
public class NoAuthenticateAttribute : RequestFilterAttribute {

    public NoAuthenticateAttribute() : this(ApplyTo.All) {}

    public NoAuthenticateAttribute(ApplyTo applyTo) : base(applyTo) {
        // execute this before any AuthenticateAttribute executes.
        // https://github.com/ServiceStack/ServiceStack/wiki/Order-of-Operations
        Priority = this.Priority = ((int) RequestFilterPriority.Authenticate) - 1;
    }

    public override void Execute(IHttpRequest req, IHttpResponse res, object requestDto)
    {
        req.Items["SkipAuthentication"] = true;
    }
}

And create a custom subclass of AuthenticateAttribute that checks for that flag in the request:

public class MyAuthenticateAttribute : AuthenticateAttribute {
    public override void Execute(IHttpRequest req, IHttpResponse res, object requestDto)
    {
        if (!ShouldSkipAuthenticationFor(req))
            base.Execute(req, res, requestDto);
    }

    private bool ShouldSkipAuthenticationFor(IHttpRequest req)
    {
        return req.Items.ContainsKey("SkipAuthentication");
    }
}

Usage:

[MyAuthenticate]
public class MyService : Service
{
    public object Get(DtoThatNeedsAuthentication obj)
    {
        // this will be authenticated
    }

    [NoAuthenticate]
    public object Get(DtoThatShouldNotAuthenticate obj)
    {
        // this will not be authenticated
    }
}
like image 191
Mike Mertsock Avatar answered Oct 08 '22 01:10

Mike Mertsock