Search code examples
authenticationservicestackapi-key

ServiceStack authentication with both [Authenticate] and [ValidateApiKey] attributes


I have some endpoints decorated with the [Authenticate] attribute. Now a third party client has to access the same endpoint by using a shared API key.

As the code would be exactly the same for the two cases, I would like to check first if the current request comes from an authenticated user and, if not, checks as fallback if a valid API key is provided.

Is there a way to use both [Authenticate] and [ValidateApiKey] attributes for the same endpoint?

Something like:

[Authenticate | ValidateApiKey]
public long Post(MyDto request)
{
   // ....
}

Solution

  • Attributes can only be combined to add functionality, i.e. they can't be used as a fallback or a switch. To get the desired behavior your [ValidateApiKey] attribute should perform the validation fallback as part of its implementation, e.g:

    public class ValidateApiKeyAttribute : RequestFilterAttribute
    {
        public override void Execute(IRequest req, IResponse res, object reqDto)
        {
            var session = req.GetSession();
            if (session == null || !session.IsAuthenticated)
            {
                //If not a valid key, execute the `[Authenticate]` attribute 
                //to handle failed response
                if (!CheckValidApiKey(req))
                    new AuthenticateAttribute().Execute(req,res,reqDto);
            }            
        }
    }
    

    Note: Responses should be reference types (e.g. DTO's) or raw strings not value types.

    public object Post(MyDto request)
    {
       // ....
    }