Return 401 for invalid token even if method is marked AllowAnonymous

Viewed 491

Using .Net framework, Web Api.

I have the [Authorize] attribute on my controller and [AllowAnonymous] on some endpoints.

I have several endpoints which allows anonymous, but return different (more) data if a user is authenticated.

If a user has an expired token, they currently get the anonymous version of the data.

What I would like to do is if a token is present in the request header and the token is invalid (typically because it is expired), I would like to return 401 even though the method is marked [AllowAnonymous].

(that will trigger the client to get a new token and get the authenticated data, rather than silently getting only a subset of the data)

Thank you

Edit to clarify: what I'm looking for is a filter that will check if User.Identity.IsAuthenticated is false but there is a authorization bearer token in the request the filter should return the 401 despite the method being marked as [AllowAnonymous].

1 Answers

I did it by overriding the AuthorizeAttribute.

public class AuthorizeCustomAttribute : System.Web.Http.AuthorizeAttribute
{

    public override void OnAuthorization(System.Web.Http.Controllers.HttpActionContext actionContext)
    {
        if (actionContext == null)
        {
            throw new ArgumentNullException("actionContext");
        }

        if (SkipAuthorization(actionContext))
        {
            return;
        }

        if (!IsAuthorized(actionContext))
        {
            HandleUnauthorizedRequest(actionContext);
        }
    }

    private static bool SkipAuthorization(System.Web.Http.Controllers.HttpActionContext actionContext)
    {
        //override default logic.
        //If there is a authorization header, return unauthorized even if method is marked AllowAnonymous

        System.Diagnostics.Contracts.Contract.Assert(actionContext != null);

        if (actionContext.ActionDescriptor.GetCustomAttributes<System.Web.Http.AllowAnonymousAttribute>().Any()
               || actionContext.ControllerContext.ControllerDescriptor.GetCustomAttributes<System.Web.Http.AllowAnonymousAttribute>().Any())
        {

            if (actionContext.Request.Headers.Authorization == null) return true;
        }
        return false;
    }
}
Related