Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

This has had me stumped for a while. None of the commonly encountered similar situations seem to apply here apparently. I've probably missed something obvious but I can't see it.

In my Mvc Web Application I use the Authorize and AllowAnonymous attributes in such a way that you have to explicitly open up an action as publicly available rather than lock down the secure areas of the site. I much prefer that approach. I cannot get the same behaviour in my WebAPI however.

I have written a custom Authorization Attribute that inherits from System.Web.Http.AuthorizeAttribute with the following:

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
public class MyAuthorizationAttribute : System.Web.Http.AuthorizeAttribute

I have this registered as a filter:

    public static void RegisterHttpFilters(HttpFilterCollection filters)
    {
        filters.Add(new MyAuthorizationAttribute());
    }

This all works as expected, actions are no longer available without credentials. The problem is that now the following method will not allow the AllowAnonymous attribute to do it's thing:

[System.Web.Http.AllowAnonymous]
public class HomeController : ApiController
{
    [GET("/"), System.Web.Http.HttpGet]
    public Link[] Index()
    {
        return new Link[] 
        { 
            new SelfLink(Request.RequestUri.AbsoluteUri, "api-root"),
            new Link(LinkRelConstants.AuthorizationEndpoint, "OAuth/Authorize/", "authenticate"),
            new Link(LinkRelConstants.AuthorizationTokenEndpoint , "OAuth/Tokens/", "auth-token-endpoint")
        };
    }
}

The most common scenario seems to be getting the two Authorize / AllowAnonymous attributes mixed up. System.Web.Mvc is for web apps and System.Web.Http is for WebAPI (as I understand it anyway).

Both of the Attributes I'm using are from the same namespace - System.Web.Http. I assumed that this would just inherit the base functionality and allow me to inject the code I need in the OnAuthotize method.

According to the documentation the AllowAnonymous attribute works inside the OnAuthorize method which I call immediately:

    public override void OnAuthorization(HttpActionContext actionContext)
    {
        base.OnAuthorization(actionContext);

Any thought's would be really appreciated.

Has anyone encountered this problem before and found the root cause?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
835 views
Welcome To Ask or Share your Answers For Others

1 Answer

In the AuthorizeAttribute there is the following code:

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

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

Include this method in your AuthorizeAttribute class then add the following to the top of your OnAuthorization method to skip authorization if any AllowAnonymous attributes are found:

if (SkipAuthorization(actionContext)) return;

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...