【问题标题】:ASP.net Web API 2 controller with multiple authentication filters具有多个身份验证过滤器的 ASP.net Web API 2 控制器
【发布时间】:2015-03-27 19:38:21
【问题描述】:

多个身份验证过滤器的预期语义是什么?是允许的吗?如果是这样,它们如何协同工作?

这是一个具体的例子。假设我有一个控制器类,例如

[BasicAuthenticator]
[LocalAuthenticator]
[Authorize]
public class TestController : ApiController
{
    [AllowAnonymous]
    public IHttpActionResult GetProduct(int id)
    {
    }

    // etc. etc
}

BasicAuthenticator 和 LocalAuthenticator 在其中实现了 IAuthenticationFilter。

每个身份验证者都有机会成功。如果其中任何一个成功,它会将context.Principal 设置为具有适当ClaimsIdentity(名称、类型和isAuthenticated = true)的新对象。

如果身份验证器失败怎么办?我认为它应该什么都不做,这样另一个人就有机会成功。对吧?

如果两者都成功呢?第二个是否会擦除第一个创建的委托人?将两个 Principal 对象的 ClaimsIdentity 集合合并在一起不是更有意义吗?

如果验证器失败,它应该什么都不做,对吗?因为其他身份验证器可能会成功。拥有两个身份验证器的语义是,如果其中一个成功,则该操作将运行,对吗?

我认为 Authorize 类将查看主体中的所有 ClaimsIdentity,如果任何 ClaimsIdentity 具有“isAuthenticated = true”,那么它将允许控制器操作运行。否则,它将设置状态 = 401。这似乎是它的工作原理。对吗?

[AllowAnonymous] 的目的是禁用所有其他授权过滤器,对吗?控制器(或操作方法)用[AllowAnonymous] 装饰,然后我假设它应该始终运行,即使身份验证失败。对吗?

【问题讨论】:

    标签: .net web-services authentication authorization asp.net-web-api2


    【解决方案1】:

    随着最近在 Web API 2 中引入的身份验证过滤器,我想应该引入 one 属性进行身份验证,并可能引入 one 属性进行授权,作为 MS 团队把这两个问题分开。所以语义是有一个一个进行身份验证。

    在我看来,您可以添加多个身份验证属性这一事实只是巧合,因为您碰巧在控制器上设置过滤器及其操作属性,并且您可以添加多个属性...在项目范围内设置身份验证过滤器也是如此,在所有控制器的所有操作上:因为一个可以添加多个过滤器,它不一定意味着一个 应该添加多个身份验证过滤器。

    如果您需要支持一种以上的身份验证机制(例如BasicLocal),您可以只使用一个属性/过滤器来拦截请求,并尝试两种机制,实现任何一个 AND/OR您可能需要的自定义逻辑。

    【讨论】:

    • 这不是真的。阅读 MS 的这篇博文,asp.net/web-api/overview/security/authentication-filters,特别是其中写着“如果……过滤器无法识别身份验证方案,则什么也不做并返回(无操作)。管道中的另一个过滤器可能会理解该方案。”这意味着可以有多个身份验证过滤器。
    • 你是对的。我想我没有以最好的方式表达自己。关键是一个可以有多个属性/过滤器,但组合它们的逻辑不能定制。相反,它以某种方式从上面强加:如果身份验证通过,则设置身份(或其他内容)并继续下一个过滤器/属性。如果失败,基​​本上应该跳过链中的所有后续步骤。因此,如果以下再次是另一个身份验证,它基本上是无用的:要么会发现身份已经设置,要么甚至可能不会被调用。
    • EDIT 在它具体说明多个身份验证过滤器的链接应该如何工作的位之前,我找不到。它位于 实现 AuthenticateAsync 方法 部分。这就是开箱即用的链接逻辑。
    • 这可能是一个不寻常的多重情况:我的整个网站需要用户名/密码验证才能访问页面。这些页面的一个子集需要管理员密码。您没有以其他用户身份登录,只是被要求提供额外的凭据以临时访问管理页面。所以 all 控制器需要主要的身份验证过滤器,管理员控制器还需要额外的过滤器来挑战管理员密码。大多数情况下,您会使用角色/声明来执行此操作,但在这种情况下,多个用户在主凭据下工作。
    【解决方案2】:

    成功运行的最后一个身份验证过滤器只会破坏 Principal。当您查看 Principal 对象和附加到它的极其复杂的 Claims 集合时,您会认为所有这些复杂性肯定是为了支持多个成功的身份验证!但你错了。只有一个人可以成功。除了放纵微软某些架构师的虚荣心之外,没有理由这么复杂。

    【讨论】:

    • 身份验证的范式更像是“一种身份验证方法”。 ClaimsPrincipal 可用于查询其多个底层 ClaimsIdentity 实例。您是否尝试过让每个过滤器简单地向现有主体添加一个新身份,而不是构建一个新主体?
    猜你喜欢
    • 1970-01-01
    • 2015-04-25
    • 2016-12-11
    • 2017-06-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-11
    • 2023-04-08
    相关资源
    最近更新 更多