【问题标题】:What OverrideAuthenticationAttribute is for?OverrideAuthenticationAttribute 是干什么用的?
【发布时间】:2014-12-20 09:33:30
【问题描述】:

我在当前的 Web API 项目中遇到了一个标有 System.Web.Http.OverrideAuthenticationAttribute 的控制器方法,我很好奇这是做什么用的?

在 Google 和 Stackoverflow 中搜索并不能回答问题。 MSDN documentation 不包含太多信息。它只说以下内容:

表示覆盖身份验证过滤器的过滤器属性 在更高级别定义。

另外,我查看了来源:

public sealed class OverrideAuthenticationAttribute : Attribute, IOverrideFilter, IFilter
{
    public bool AllowMultiple
    {
        get
        {
            return false;
        }
    }

    public Type FiltersToOverride
    {
        get
        {
            return typeof(IAuthenticationFilter);
        }
    }
}

但这并不能说明什么。

那么谁能解释一下使用OverrideAuthenticationAttribute的目的是什么?并请给出一些使用案例以便更好地理解。

【问题讨论】:

    标签: c# asp.net .net web-services asp.net-web-api


    【解决方案1】:

    OverrideAuthentication 属性用于抑制全局身份验证过滤器,这意味着使用此过滤器时将禁用所有全局身份验证过滤器(实现 IAuthenticationFilter)。

    假设您有一个名为 BasicAuth 的全局身份验证过滤器:

    public class BasicAuthAttribute : ActionFilterAttribute, IAuthenticationFilter
    {
        public void OnAuthentication(AuthenticationContext filterContext)
        { }
    
        public void OnAuthenticationChallenge(AuthenticationChallengeContext filterContext)
        {
            var user = filterContext.HttpContext.User;
            if (user == null || !user.Identity.IsAuthenticated)
            {
                filterContext.Result = new HttpUnauthorizedResult();
            }
        }
    }
    

    并且过滤器被配置为使用此代码的所有控制器的全局过滤器:

    public class FilterConfig
    {
        public static void RegisterGlobalFilters(GlobalFilterCollection filters)
        {
            filters.Add(new HandleErrorAttribute());
            filters.Add(new BasicAuthAttribute());
        }
    }
    

    假设您想对单个控制器或控制器操作使用不同的身份验证策略。在这种情况下,您可以禁用全局身份验证。使用OverrideAuthentication 属性过滤,然后配置要用于该特定操作的新过滤器。当您与外部登录提供程序集成时,这很有帮助,并且您不希望任何现有的全局身份验证过滤器弄乱您的外部登录身份验证。

    在下面的代码中,全局身份验证过滤器被禁用,然后为单个操作启用 HostAuthentication 过滤器以启用外部登录提供程序(例如 Facebook):

    // GET api/Account/ExternalLogin
    [OverrideAuthentication]
    [HostAuthentication(Startup.ExternalCookieAuthenticationType)]
    [AllowAnonymous]
    [HttpGet("ExternalLogin", RouteName = "ExternalLogin")]
    public async Task<IHttpActionResult> ExternalLogin(string provider)
    {
        // Auth code
    }
    

    【讨论】:

    • 为什么,在您的示例中,您的 BasicAuthAttribute 派生自 ActionFilterAttribute 而不是 AuthorizationAttribute
    • 它可能有,但我不想覆盖现有的 Auth 过滤器,而是实施一个新过滤器。这就是为什么我继承 ActionFilter 属性并实现 IAuthenticationFilter :)
    • @ZenCoder,感谢您的回答和清晰的代码示例!
    • @FarisZacina 你能在这里使用 AuthorizationFilter 吗,你对 Erik Phillips 的回复 - 这是否意味着 Authorization 属性是一个 Authentication 属性。或派生自一个?
    【解决方案2】:

    OverrideAuthentication 用于覆盖在更高级别配置的身份验证过滤器。比如说,你有一个像这样全局应用的身份验证过滤器。

    // Applied globally in WebApiConfig    
    config.Filters.Add(new MyAuthenticationFilter());
    

    而且,您希望阻止此过滤器针对特定操作方法或控制器运行。你可以在那个级别使用OverrideAuthentication,就像这样。

    public class ValuesController : ApiController
    {
        [OverrideAuthentication]
        public string Get()
        { ...  }
    }
    

    现在,在上面的示例中,您已在全局范围内应用了 MyAuthenticationFilter。说,您想覆盖它并运行另一个过滤器,例如 MyAnotherAuthenticationFilter 仅用于 Post 操作方法。你可以这样做。

    public class ValuesController : ApiController
    {
        // Removes all filters applied globally or at the controller level
        [OverrideAuthentication]
        [MyAnotherAuthentication] // Puts back only MyAnotherAuthenticationFilter
        public string Post(...)
        { ... }
    }
    

    更多信息here。查看“过滤器覆盖”部分。

    【讨论】:

    • 感谢您的回答,尤其感谢您提供指向您的综合 MSDN 杂志文章的链接!这是我目前读过的关于 Web API 安全性的最佳读物!
    猜你喜欢
    • 1970-01-01
    • 2016-10-30
    • 2017-11-03
    • 2021-07-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多