自定义Api授权忽略AllowAnonymous

时间:2013-10-29 23:58:32

标签: c# asp.net-mvc custom-attributes

我有一个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);
    }
}

我有一个控制器:

[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;
    }
 }

尝试调用此操作时,我一直收到401 Unauthorized错误消息。调试告诉我,authorizeattribute没有检测到[AllowAnonymous]的存在,但我不明白为什么。

任何人都可以看到我做错了吗?或者知道其他什么东西可能会有冲突吗?

1 个答案:

答案 0 :(得分:17)

如果您查看System.Web.Http.AuthorizeAttribute的源代码,请检查是否应该跳过授权:

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();
    }

所以我所做的是在我的自定义授权属性中实现类似的检查。