ASP.NET Core 身份验证概述

作者:Mike Rousos

身份验证是确定用户身份的过程。 授权是确定用户是否有权访问资源的过程。 在 ASP.NET Core 中,身份验证由 IAuthenticationService 负责,而它供身份验证中间件使用。 身份验证服务会使用已注册的身份验证处理程序来完成与身份验证相关的操作。 与身份验证相关的操作示例包括:

  • 对用户进行身份验证。
  • 在未经身份验证的用户试图访问受限资源时作出响应。

已注册的身份验证处理程序及其配置选项被称为“方案”。

身份验证方案由 Startup.ConfigureServices 中的注册身份验证服务指定:

例如,下列代码会为 cookie 和 JWT 持有者身份验证方案注册身份验证服务和处理程序:

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, options => Configuration.Bind("JwtSettings", options))
    .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, options => Configuration.Bind("CookieSettings", options));

AddAuthentication 参数 JwtBearerDefaults.AuthenticationScheme 是方案的名称,未请求特定方案时会默认使用此名称。

如果使用了多个方案,授权策略(或授权属性)可指定对用户进行身份验证时要依据的一个或多个身份验证方案。 在上例中,可通过指定 cookie 身份验证方案的名称来使用该方案(默认为 CookieAuthenticationDefaults.AuthenticationScheme,但也可在调用 AddCookie 时提供其他名称)。

在某些情况下,其他扩展方法会自动调用 AddAuthentication。 例如,在使用 ASP.NET Core Identity 时,会在内部调用 AddAuthentication

通过在应用的 IApplicationBuilder 上调用 UseAuthentication 扩展方法,在 Startup.Configure 中添加身份验证中间件。 如果调用 UseAuthentication,会注册使用之前注册的身份验证方案的中间节。 请在依赖于要进行身份验证的用户的所有中间件之前调用 UseAuthentication。 如果使用终结点路由,则必须按以下顺序调用 UseAuthentication

  • UseRouting之后调用,以便路由信息可用于身份验证决策。
  • UseEndpoints 之前调用,以便用户在经过身份验证后才能访问终结点。

身份验证概念

身份验证负责提供 ClaimsPrincipal 进行授权,以针对其进行权限决策。 可通过多种身份验证方案方法来选择使用哪种身份验证处理程序负责生成正确的声明集:

不会自动探测方案。 如果未指定默认方案,则必须在授权属性中指定该方案,否则将引发以下错误:

InvalidOperationException:未指定任何 authenticationScheme,并且未找到 DefaultAuthenticateScheme。 可使用 AddAuthentication(string defaultScheme) 或 AddAuthentication(Action<AuthenticationOptions> configureOptions) 设置默认方案。

身份验证方案

身份验证方案可选择使用哪种身份验证处理程序负责生成正确的声明集。 有关详细信息,请参阅使用特定方案授权

身份验证方案是与下列项相对应的名称:

  • 身份验证处理程序。
  • 用于配置处理程序的该特定实例的选项。

方案可用作一种机制,供用户参考相关处理程序的身份验证、挑战和禁止行为。 例如,授权策略可使用方案名称来指定应使用哪种(或哪些)身份验证方案来对用户进行身份验证。 配置身份验证时,通常是指定默认身份验证方案。 除非资源请求了特定方案,否则使用默认方案。 还可:

  • 指定其他默认方案供授权、挑战和禁止操作使用。
  • 可通过策略方案将多个方案合成一个。

身份验证处理程序

身份验证处理程序:

根据身份验证方案的配置和传入的请求上下文,身份验证处理程序:

  • 构造表示用户身份的 AuthenticationTicket 对象(若身份验证成功)。
  • 返回“无结果”或“失败”(若身份验证失败)。
  • 具有用于挑战和禁止操作的方法,供用户在下述情况下访问资源时使用:
    • 他们未获得访问授权(禁止)。
    • 他们未经过身份验证(挑战)。

Authenticate

身份验证方案的身份验证操作负责根据请求上下文构造用户的身份。 它会返回一个 AuthenticateResult指示身份验证是否成功;若成功,则还在身份验证票证中指示用户的身份。 请参阅 AuthenticateAsync。 身份验证示例包括:

  • 根据 cookie 构造用户身份的 cookie 身份验证方案。
  • 对 JWT 持有者令牌进行反序列化和验证以构造用户身份的 JWT 持有者方案。

挑战

当未经身份验证的用户请求要求身份验证的终结点时,授权会发起身份验证挑战。 例如,当匿名用户请求受限资源或单击登录链接时,会引发身份验证挑战。 授权会使用指定的身份验证方案发起挑战;如果未指定任何方案,则使用默认方案。 请参阅 ChallengeAsync。 身份验证挑战示例包括:

  • 将用户重定向到登录页面的 cookie 身份验证方案。
  • 返回具有 www-authenticate: bearer 标头的 401 结果的 JWT 持有者方案。

挑战操作应告知用户要使用哪种身份验证机制来访问所请求的资源。

禁止

当已经过身份验证的用户尝试访问其无权访问的资源时,授权会调用身份验证方案的禁止操作。 请参阅 ForbidAsync。 身份验证禁止示例包括:

  • 将用户重定向到表示访问遭禁的页面的 cookie 身份验证方案。
  • 返回 403 结果的 JWT 持有者方案。
  • 重定向到用户可请求资源访问权限的页面的自定义身份验证方案。

用户可通过禁止操作知道:

  • 他们已经过身份验证。
  • 他们无权访问所请求的资源。

请查看以下链接,了解挑战与禁止之间区别:

每个租户的身份验证提供程序

ASP.NET Core 框架没有用于多租户身份验证的内置解决方案。 虽然客户当然可以使用内置功能编写一个解决方案,但建议客户查看 Orchard Core 以实现此目的。

Orchard Core 是:

  • 使用 ASP.NET Core 生成的开放源代码模块和多租户应用框架。
  • 基于该应用框架生成的内容管理系统 (CMS)。

请参阅 Orchard Core 源,了解每个租户的身份验证提供程序的示例。

其他资源