OverrideAuthenticationAttribute的作用是什么?

15

在我的Web API项目中,我发现了一个被标记为System.Web.Http.OverrideAuthenticationAttribute的控制器方法,我想知道它有什么作用?在Google和Stackoverflow中搜索都没有回答这个问题。MSDN文档没有提供太多信息。它只是说:

表示一个过滤器属性,覆盖在更高层定义的身份验证过滤器。

此外,我已经查看了源代码:

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

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

但这并没有提供太多的信息。

那么,有人能解释一下使用OverrideAuthenticationAttribute的目的是什么吗?并且可以给出一些使用案例以便更好地理解。

2个回答

17

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 - Erik Philips
1
它本来可以这样做,但我不想覆盖现有的Auth过滤器,而是实现一个新的。这就是为什么我继承ActionFilter属性并实现IAuthenticationFilter的原因 :) - Faris Zacina
@ZenCoder,感谢你的答案和清晰的代码示例! - Alexander Abakumov
@FarisZacina,你能在这里使用AuthorizationFilter吗?还有你对Erik Phillips的回复——这是否意味着Authorization属性是一个Authentication属性或者从一个Authentication属性派生而来? - SpiritBob

4

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

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

如果你想要停止某个过滤器对于特定的操作方法或者控制器的运行,你可以在这个级别上使用 OverrideAuthentication,像这样。

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

在上面的例子中,你已经全局应用了MyAuthenticationFilter。假如说,你想要覆盖它并且只为Post操作方法运行另一个过滤器,比如MyAnotherAuthenticationFilter。你可以像这样操作:

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

更多信息在此处查看。请查看“筛选器覆盖”部分。


感谢你的答案,特别是分享你全面的 MSDN 杂志文章链接!这是我迄今为止阅读过的有关 Web API 安全性的最佳内容! - Alexander Abakumov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接