Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom Api Authorize ignoring AllowAnonymous

I have a CustomApiAuthorizeAttribute:

public class CustomApiAuthorizeAttribute : AuthorizeAttribute
{
    public override void OnAuthorization(HttpActionContext actionContext)
    {
        if (actionContext == null)
            throw new ArgumentNullException("actionContext");

        bool skipAuthorization = actionContext.ActionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().Any() || 
            actionContext.ActionDescriptor.ControllerDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().Any();

        if (skipAuthorization) return;

        var cookie = HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName];

        if (cookie != null)
        {
            var decCookie = FormsAuthentication.Decrypt(cookie.Value);

            if (decCookie != null)
            {
                if (!string.IsNullOrEmpty(decCookie.UserData))
                {
                    HttpContext.Current.User = new CustomPrinciple(new CustomIdentity(decCookie));
                    return;
                }
            }
        }

        HttpContext.Current.Items["RequestWasNotAuthorized"] = true;

        HttpContext.Current.Response.Cookies.Add(new HttpCookie(FormsAuthentication.FormsCookieName) { Expires = DateTime.Now.AddDays(-1d) });

        HandleUnauthorizedRequest(actionContext);
    }
}

And I have a controller:

[CustomApiAuthorize]
public class RacingController : CustomApiController
{
    [HttpGet]
    [AllowAnonymous]
    public Venues Venues()
    {
        var asr = Services.GetVenues(Token);
        if(!string.IsNullOrEmpty(Token))
            SetAuthTicket(asr.Token);
        return asr.Payload;
    }
 }

I keep getting a 401 Unauthorized error when trying to call this action. Debugging tells me that the authorizeattribute is not detecting the presence of the [AllowAnonymous] but I don't understand why.

Can any one see what I am doing wrong? or have any idea if something else could be conflicting?

like image 358
Zholen Avatar asked Oct 29 '13 23:10

Zholen


1 Answers

If you look in the source of the System.Web.Http.AuthorizeAttribute, there is the following check to see if Authorization should be skipped:

public override void OnAuthorization(HttpActionContext actionContext)
    {
        if (actionContext == null)
        {
            throw Error.ArgumentNull("actionContext");
        }

        if (SkipAuthorization(actionContext))
        {
            return;
        }

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

        private static bool SkipAuthorization(HttpActionContext actionContext)
    {
        Contract.Assert(actionContext != null);

        return actionContext.ActionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().Any()
               || actionContext.ControllerContext.ControllerDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().Any();
    }

So what I did was implement a similar check within my custom authorization attributes.

like image 193
JTech Avatar answered Sep 18 '22 22:09

JTech