这让我陷入了一段时间。没有什么常见的类似情况似乎在这里明显适用。我可能错过了一些明显的东西,但我看不到它。
在我的Mvc Web应用程序中,我使用Authorize和AllowAnonymous属性,您必须显式地打开一个操作为公开可用,而不是锁定网站的安全区域。我更喜欢这种方法。我不能在我的WebAPI中得到相同的行为。
我写了一个自定义的授权属性,继承自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方法中需要的代码。
根据文档,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类中,然后将以下内容添加到OnAuthorization方法的顶部,以在找到任何AllowAnonymous属性时跳过授权:
if (SkipAuthorization(actionContext)) return;