AllowAnonymous不使用Custom AuthorizationAttribute

Jam*_*mer 51 authentication asp.net-mvc attributes asp.net-web-api

这让我难以忍受了一段时间.通常遇到的类似情况似乎都不适用于此.我可能错过了一些明显但我看不到的东西.

在我的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
Run Code Online (Sandbox Code Playgroud)

我将此注册为过滤器:

    public static void RegisterHttpFilters(HttpFilterCollection filters)
    {
        filters.Add(new MyAuthorizationAttribute());
    }
Run Code Online (Sandbox Code Playgroud)

这一切都按预期工作,没有凭据就不再提供操作.问题是现在以下方法不允许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")
        };
    }
}
Run Code Online (Sandbox Code Playgroud)

最常见的情况似乎是将两个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);
Run Code Online (Sandbox Code Playgroud)

任何想法都会非常感激.

有没有人遇到过这个问题,找到根本原因?

Jam*_*mer 82

在AuthorizeAttribute中有以下代码:

private static bool SkipAuthorization(HttpActionContext actionContext)
{
    Contract.Assert(actionContext != null);

    return actionContext.ActionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().Any()
               || actionContext.ControllerContext.ControllerDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().Any();
}
Run Code Online (Sandbox Code Playgroud)

在AuthorizeAttribute类中包含此方法,然后将以下内容添加到OnAuthorization方法的顶部,以便在找到任何AllowAnonymous属性时跳过授权:

if (SkipAuthorization(actionContext)) return;
Run Code Online (Sandbox Code Playgroud)

  • 请注意,此代码具有反直觉行为:控制器上的`[AllowAnonymous]`属性将覆盖**方法上的任何授权属性.为了防止这种情况,您可以针对`IAuthorizationFilter`(或您正在使用的任何基类/接口)添加针对`ActionDescriptor`的另一个自定义属性检查,并且只有当匿名控制器为真时才跳过身份验证. (4认同)
  • 没错,但我认为这也是一个设计问题.如果您在同一个控制器上混合安全和非安全操作,那么就该移动它了. (4认同)

g.b*_*eze 27

ASP.NET MVC 4:

bool skipAuthorization = filterContext.ActionDescriptor.IsDefined(typeof(AllowAnonymousAttribute), true)
                         || filterContext.ActionDescriptor.ControllerDescriptor.IsDefined(typeof(AllowAnonymousAttribute), true);
Run Code Online (Sandbox Code Playgroud)

要么

 private static bool SkipAuthorization(AuthorizationContext filterContext)
    {
        Contract.Assert(filterContext != null);

        return filterContext.ActionDescriptor.GetCustomAttributes(typeof(AllowAnonymousAttribute), true).Any()
               || filterContext.ActionDescriptor.ControllerDescriptor.GetCustomAttributes(typeof(AllowAnonymousAttribute), true).Any();
    }
Run Code Online (Sandbox Code Playgroud)

Soruce:http://weblogs.asp.net/jongalloway/asp-net-mvc-authentication-global-authentication-and-allow-anonymous

  • 我来到这里希望我可以将海报问题调整为我在 MVC 中遇到的相同问题。感谢这个答案,满意地离开。 (2认同)

Ano*_*aly 10

就我而言,上述解决方案均无效。我正在使用带有自定义功能的 .Net Core 3.1,IAuthorizationFilter我必须执行以下操作:

public void OnAuthorization(AuthorizationFilterContext context)
    {
        if (context.ActionDescriptor.EndpointMetadata.OfType<AllowAnonymousAttribute>().Any()) return;
Run Code Online (Sandbox Code Playgroud)