我正在尝试在 MVC4/Razor 中创建自定义授权属性,并且遇到在自定义授权属性下运行的“AllowAnnoymous”属性的问题(它似乎忽略它)。这一切都很好,花花公子,因为我通过检查控制器或动作是否包含允许匿名属性然后允许传递(如果是这样)来找到解决方案(见下文)。
但是,我看到当我创建“AuthorizeAttribute”类并尝试实现“OnAuthorization”覆盖时,它将对象处理程序设置为“AuthorizationContext”类型,但在下面的示例中以及我在此处找到的许多其他,似乎不应该使用“AuthorizationContext” - 而应该是“HttpActionContext”。虽然我试图用“HttpActionContext”替换它,然后覆盖失败,说没有合适的方法。关于我 missing/doing 错误的任何想法?
private static bool SkipAuthorization(HttpActionContext actionContext)
{
Contract.Assert(actionContext != null);
return actionContext.ActionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().Any()
|| actionContext.ControllerContext.ControllerDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().Any();
}
public override void OnAuthorization(HttpActionContext actionContext)
{
base.OnAuthorization(actionContext);
}
我的守则
private override void OnAuthorization(AuthorizationContext filterContext) // Not sure how to change this to HttpActionContext
{
if (filterContext == null) throw new ArugmentException("filterContext");
if (!AllowAnnonymous(new HttpActionContext()))
{
throw new HttpResponseException(HttpStatusCode.UnAuthorized);
}
else
{
base.OnAuthorization(filterContext);
}
}
1 回答
首先,您正在查看使用Web API System.Web.Http.AuthorizeAttribute而不是MVC System.Web.Mvc.AuthorizeAttribute的示例。 MVC 和 Web API 是独立的框架,也不会识别其他的属性。这也是为什么在
AuthorizeAttribute
中有不同的上下文类型的原因。其次,你的自定义
AuthorizeAttribute
无法识别AllowAnonymousAttribute
的原因是因为你要覆盖OnAuthorization
中检查的逻辑(以及处理输出缓存的其他重要逻辑)。如果您改为覆盖AuthorizeCore
并返回 true/false,那么您将不会跳过这个重要的逻辑。如果需要更改用户重定向的位置,可以覆盖
HandleUnauthorizedRequest
,仅在授权失败时执行。最后,如果您需要访问
ActionDescriptor
来扫描您自己的属性,它将通过AuthorizationContext.ActionDescriptor
传递到OnAuthorization
。不幸的是,它没有自动传递到AuthorizeCore
,但你可以通过在OnAuthorization
中设置为HttpContext.Items
来解决这个问题,如这个例子。