这让我难过了一段时间。似乎没有一种通常遇到的类似情况在这里适用。我可能错过了一些显而易见的东西,但我看不到。
在我的Mvc Web应用程序中,我使用Authorize和AllowAnonymous属性的方式是,您必须显式地将操作公开公开,而不是锁定站点的安全区域。我更喜欢这种方法。但是,我无法在WebAPI中获得相同的行为。
我编写了一个自定义的Authorization Attribute,它继承自System.Web.Http.AuthorizeAttribute并具有以下内容:
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
public class MyAuthorizationAttribute : System.Web.Http.AuthorizeAttribute
我已将此注册为过滤器:
public static void RegisterHttpFilters(HttpFilterCollection filters)
{
filters.Add(new MyAuthorizationAttribute());
}
所有这些都按预期工作,没有凭据就无法再执行操作。问题在于,现在以下方法将不允许AllowAnonymous属性执行此操作:
[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")
};
}
}
最常见的情况似乎是将两个Authorize / AllowAnonymous属性混合在一起。 System.Web.Mvc用于Web应用程序,而System.Web.Http用于WebAPI(据我所知)。
我正在使用的两个属性都来自同一命名空间-System.Web.Http。我假设这将继承基本功能,并允许我在OnAuthotize方法中注入(inject)所需的代码。
根据文档,AllowAnonymous属性在OnAuthorize方法中起作用,我立即调用该方法:
public override void OnAuthorization(HttpActionContext actionContext)
{
base.OnAuthorization(actionContext);
任何想法将不胜感激。
有人遇到过此问题并找到了根本原因吗?
最佳答案
在AuthorizeAttribute中,有以下代码:
private static bool SkipAuthorization(HttpActionContext actionContext)
{
Contract.Assert(actionContext != null);
return actionContext.ActionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().Any()
|| actionContext.ControllerContext.ControllerDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().Any();
}
在AuthorizeAttribute类中包含此方法,然后在找到的AllowAnonymous属性后,将以下内容添加到OnAuthorization方法的顶部,以跳过授权:
if (SkipAuthorization(actionContext)) return;