C# CustomAuthorizationAttribute-HttpActionContext而不是AuthorizationContext
我试图在MVC4/Razor中创建一个自定义授权属性,但在自定义授权属性下运行的“allowanonymous”属性有问题(它似乎忽略了它)。这一切都很好,因为我找到了一个解决方案(见下文),通过检查控制器或操作是否包含allow anonymous属性,然后检查allow pass-through(如果是) 然而,我看到当我创建“AuthorizationAttribute”类并尝试实现“OnAuthorization”覆盖时,它将对象处理程序设置为“AuthorizationContext”类型,但在下面的示例和我在这里发现的许多其他示例中,似乎不应该使用“AuthorizationContext”,而应该是“HttpActionContext”. 虽然我试图用“HttpActionContext”替换它,但是覆盖失败了,因为没有合适的方法。你知道我错过了什么/做错了什么吗 你知道我错过了什么/做错了什么吗 首先,您将看到一个使用而不是的示例。MVC和WebAPI是独立的框架,两者都不能识别对方的属性。这也是为什么在C# CustomAuthorizationAttribute-HttpActionContext而不是AuthorizationContext,c#,asp.net-mvc-4,authorization,C#,Asp.net Mvc 4,Authorization,我试图在MVC4/Razor中创建一个自定义授权属性,但在自定义授权属性下运行的“allowanonymous”属性有问题(它似乎忽略了它)。这一切都很好,因为我找到了一个解决方案(见下文),通过检查控制器或操作是否包含allow anonymous属性,然后检查allow pass-through(如果是) 然而,我看到当我创建“AuthorizationAttribute”类并尝试实现“OnAuthorization”覆盖时,它将对象处理程序设置为“AuthorizationContext”
authorized属性中有不同的上下文类型的原因
其次,您的自定义AuthorizeAttribute
无法识别AllowAnonymousAttribute
的原因是,您正在重写签入OnAuthorization
的逻辑(以及处理输出缓存的其他重要逻辑)。如果您改为重写AuthorizeCore
并返回true/false,则不会跳过此重要逻辑
如果需要更改用户重定向的位置,可以覆盖HandleUnauthorizedRequest
,它仅在授权失败时执行
最后,如果您需要访问ActionDescriptor
来扫描您自己的属性,它将通过authorization context.ActionDescriptor
传递到OnAuthorization
。不幸的是,它没有自动传递到AuthorizeCore
,但是您可以通过将其设置为HttpContext.Items来解决这个问题。。我想我没有研究不同的authorize属性/没有意识到WebAPI使用了与MVC不同的属性。与MVC相比,在这个场景中是否可以使用System.Web.Http.authorized属性?我还将检查“AuthorizeCore”覆盖,因为我肯定希望能够使用匿名属性(而不必进行大杂烩)。我真诚地感谢你的解释与MVC相比,在这种情况下是否可以使用System.Web.Http.authorized属性?
否,但不清楚为什么要这样做。如果您想在它们之间共享业务逻辑,您可以创建一个类来实现System.Web.Mvc.IAuthorizationFilter
和System.Web.Http.IAuthorizationFilter
,也可以创建一个公共服务,将其注入两个过滤器中(有关如何将DI与AuthorizeAttribute一起使用的信息,请参阅).有趣-根据我的测试和提供的链接/说明,我认为这对我来说是可行的。谢谢你的帮助!
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);
}
}