ASP.NET Core 身份验证概述
作者:Mike Rousos
身份验证是确定用户 identity 的过程。 授权是确定用户是否有权访问资源的过程。 在 ASP.NET Core 中,身份验证由身份验证服务 IAuthenticationService 负责,而它供身份验证中间件使用。 身份验证服务会使用已注册的身份验证处理程序来完成与身份验证相关的操作。 与身份验证相关的操作示例包括:
- 对用户进行身份验证。
- 在未经身份验证的用户试图访问受限资源时作出响应。
已注册的身份验证处理程序及其配置选项被称为“方案”。
身份验证方案由 Program.cs
中的注册身份验证服务指定:
- 方式是在调用 AddAuthentication 后调用方案特定的扩展方法(例如 AddJwtBearer 或 AddCookie)。 这些扩展方法使用 AuthenticationBuilder.AddScheme 向适当的设置注册方案。
- 不太常用的方法是直接调用
AuthenticationBuilder.AddScheme
。
例如,下列代码会为 cookie 和 JWT 持有者身份验证方案注册身份验证服务和处理程序:
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(JwtBearerDefaults.AuthenticationScheme,
options => builder.Configuration.Bind("JwtSettings", options))
.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme,
options => builder.Configuration.Bind("CookieSettings", options));
AddAuthentication
参数 JwtBearerDefaults.AuthenticationScheme 是方案的名称,未请求特定方案时会默认使用此名称。
如果使用了多个方案,授权策略(或授权属性)可指定对用户进行身份验证时要依据的一个或多个身份验证方案。 在上例中,可通过指定 cookie 身份验证方案的名称来使用该方案(默认为 CookieAuthenticationDefaults.AuthenticationScheme,但也可在调用 AddCookie
时提供其他名称)。
在某些情况下,其他扩展方法会自动调用 AddAuthentication
。 例如,使用 ASP.NET Core Identity 时,会在内部调用 AddAuthentication
。
通过调用 UseAuthentication,在 Program.cs
中添加身份验证中间件。 如果调用 UseAuthentication
,会注册使用之前注册的身份验证方案的中间件。 请在依赖于要进行身份验证的用户的所有中间件之前调用 UseAuthentication
。
身份验证概念
身份验证负责提供 ClaimsPrincipal 进行授权,以针对其进行权限决策。 可通过多种身份验证方案方法来选择使用哪种身份验证处理程序负责生成正确的声明集:
- 身份验证方案
- 默认身份验证方案,将在接下来的两节中讨论。
- 直接设置 HttpContext.User。
如果只注册了单个身份验证方案,则该方案将成为默认方案。 如果注册了多个方案且未指定默认方案,则必须在授权属性中指定该方案,否则将引发以下错误:
InvalidOperationException:未指定 authenticationScheme,并且未找到 DefaultAuthenticateScheme。 可使用 AddAuthentication(string defaultScheme) 或 AddAuthentication(Action<AuthenticationOptions> configureOptions) 设置默认方案。
DefaultScheme
如果只注册了单个身份验证方案,则单个身份验证方案:
- 自动用作 DefaultScheme。
- 无需指定 AddAuthentication(IServiceCollection) 或 AddAuthenticationCore(IServiceCollection) 中的
DefaultScheme
。
若要禁用自动将单个身份验证方案用作 DefaultScheme
,请调用 AppContext.SetSwitch("Microsoft.AspNetCore.Authentication.SuppressAutoDefaultScheme")
。
身份验证方案
身份验证方案可选择使用哪种身份验证处理程序负责生成正确的声明集。 有关详细信息,请参阅使用特定方案授权。
身份验证方案是与下列项相对应的名称:
- 身份验证处理程序。
- 用于配置处理程序的该特定实例的选项。
方案可用作一种机制,供用户参考相关处理程序的身份验证、挑战和禁止行为。 例如,授权策略可使用方案名称来指定应使用哪种(或哪些)身份验证方案来对用户进行身份验证。 配置身份验证时,通常是指定默认身份验证方案。 除非资源请求了特定方案,否则使用默认方案。 还可:
- 指定其他默认方案供授权、挑战和禁止操作使用。
- 可通过策略方案将多个方案合成一个。
身份验证处理程序
身份验证处理程序:
- 是一种实现方案行为的类型。
- 派生自 IAuthenticationHandler 或 AuthenticationHandler<TOptions>。
- 具有对用户进行身份验证的主要责任。
根据身份验证方案的配置和传入的请求上下文,身份验证处理程序:
- 构造表示用户 identity 的 AuthenticationTicket 对象(若身份验证成功)。
- 返回“无结果”或“失败”(若身份验证失败)。
- 具有用于挑战和禁止操作的方法,供用户在下述情况下访问资源时使用:
- 他们未获得访问授权(禁止)。
- 他们未经过身份验证(挑战)。
RemoteAuthenticationHandler<TOptions>
与 AuthenticationHandler<TOptions>
RemoteAuthenticationHandler<TOptions> 是需要远程身份验证步骤的身份验证类。 远程身份验证步骤完成后,处理程序将回调处理程序设置的 CallbackPath
。 处理程序使用传递给 HandleRemoteAuthenticateAsync 回调路径的信息完成身份验证步骤。 OAuth 2.0 和 OIDC 都使用此模式。 JWT 和 Cookie 不使用此模式,因为它们可以直接使用持有者标头和 cookie 进行身份验证。 在这种情况下,远程托管的提供程序:
Authenticate
身份验证方案的身份验证操作负责根据请求上下文构造用户的 identity。 它会返回一个 AuthenticateResult 指示身份验证是否成功;若成功,则在身份验证票证中指示用户的 identity。 请参阅 AuthenticateAsync。 身份验证示例包括:
- 根据 Cookie 构造用户 identity 的 cookie 身份验证方案。
- 对 JWT 持有者令牌进行反序列化和验证以构造用户 identity 的 JWT 持有者方案。
难题
当未经身份验证的用户请求要求身份验证的终结点时,授权会发起身份验证挑战。 例如,当匿名用户请求受限资源或访问登录链接时,会引发身份验证挑战。 授权会使用指定的身份验证方案发起挑战;如果未指定任何方案,则使用默认方案。 请参阅 ChallengeAsync。 身份验证挑战示例包括:
- 将用户重定向到登录页面的 cookie 身份验证方案。
- 返回具有
www-authenticate: bearer
标头的 401 结果的 JWT 持有者方案。
挑战操作应告知用户要使用哪种身份验证机制来访问所请求的资源。
禁止
当已经过身份验证的用户尝试访问其无权访问的资源时,授权会调用身份验证方案的禁止操作。 请参阅 ForbidAsync。 身份验证禁止示例包括:
- 将用户重定向到表示访问遭禁的页面的 cookie 身份验证方案。
- 返回 403 结果的 JWT 持有者方案。
- 重定向到用户可请求资源访问权限的页面的自定义身份验证方案。
用户可通过禁止操作知道:
- 他们已经过身份验证。
- 他们无权访问所请求的资源。
请查看以下链接,了解挑战与禁止之间区别:
每个租户的身份验证提供程序
ASP.NET Core 没有用于多租户身份验证的内置解决方案。 虽然客户可以使用内置功能编写一个,但我们建议考虑使用 Orchard Core、ABP Framework 或 Finbuckle.MultiTenant 进行多租户身份验证。
Orchard Core 是:
- 使用 ASP.NET Core 生成的开放源代码模块和多租户应用框架。
- 基于该应用框架生成的内容管理系统 (CMS)。
请参阅 Orchard Core 源,了解每个租户的身份验证提供程序的示例。
ABP Framework 支持各种体系结构模式,包括模块化、微服务、域驱动设计和多租户。 请参阅 GitHub 上的 ABP Framework 源。
Finbuckle.MultiTenant:
- 开源
- 提供租户解决方案
- 轻型
- 提供数据隔离
- 为每个租户单独配置应用行为
其他资源
作者:Mike Rousos
身份验证是确定用户 identity 的过程。 授权是确定用户是否有权访问资源的过程。 在 ASP.NET Core 中,身份验证由身份验证服务 IAuthenticationService 负责,而它供身份验证中间件使用。 身份验证服务会使用已注册的身份验证处理程序来完成与身份验证相关的操作。 与身份验证相关的操作示例包括:
- 对用户进行身份验证。
- 在未经身份验证的用户试图访问受限资源时作出响应。
已注册的身份验证处理程序及其配置选项被称为“方案”。
身份验证方案由 Program.cs
中的注册身份验证服务指定:
- 方式是在调用 AddAuthentication 后调用方案特定的扩展方法(例如 AddJwtBearer 或 AddCookie)。 这些扩展方法使用 AuthenticationBuilder.AddScheme 向适当的设置注册方案。
- 不太常用的方法是直接调用
AuthenticationBuilder.AddScheme
。
例如,下列代码会为 cookie 和 JWT 持有者身份验证方案注册身份验证服务和处理程序:
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(JwtBearerDefaults.AuthenticationScheme,
options => builder.Configuration.Bind("JwtSettings", options))
.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme,
options => builder.Configuration.Bind("CookieSettings", options));
AddAuthentication
参数 JwtBearerDefaults.AuthenticationScheme 是方案的名称,未请求特定方案时会默认使用此名称。
如果使用了多个方案,授权策略(或授权属性)可指定对用户进行身份验证时要依据的一个或多个身份验证方案。 在上例中,可通过指定 cookie 身份验证方案的名称来使用该方案(默认为 CookieAuthenticationDefaults.AuthenticationScheme,但也可在调用 AddCookie
时提供其他名称)。
在某些情况下,其他扩展方法会自动调用 AddAuthentication
。 例如,使用 ASP.NET Core Identity 时,会在内部调用 AddAuthentication
。
通过调用 UseAuthentication,在 Program.cs
中添加身份验证中间件。 如果调用 UseAuthentication
,会注册使用之前注册的身份验证方案的中间件。 请在依赖于要进行身份验证的用户的所有中间件之前调用 UseAuthentication
。
身份验证概念
身份验证负责提供 ClaimsPrincipal 进行授权,以针对其进行权限决策。 可通过多种身份验证方案方法来选择使用哪种身份验证处理程序负责生成正确的声明集:
- 身份验证方案
- 默认身份验证方案,将在下一节中讨论。
- 直接设置 HttpContext.User。
不会自动探测方案。 如果未指定默认方案,则必须在授权属性中指定该方案,否则将引发以下错误:
InvalidOperationException:未指定 authenticationScheme,并且未找到 DefaultAuthenticateScheme。 可使用 AddAuthentication(string defaultScheme) 或 AddAuthentication(Action<AuthenticationOptions> configureOptions) 设置默认方案。
身份验证方案
身份验证方案可选择使用哪种身份验证处理程序负责生成正确的声明集。 有关详细信息,请参阅使用特定方案授权。
身份验证方案是与下列项相对应的名称:
- 身份验证处理程序。
- 用于配置处理程序的该特定实例的选项。
方案可用作一种机制,供用户参考相关处理程序的身份验证、挑战和禁止行为。 例如,授权策略可使用方案名称来指定应使用哪种(或哪些)身份验证方案来对用户进行身份验证。 配置身份验证时,通常是指定默认身份验证方案。 除非资源请求了特定方案,否则使用默认方案。 还可:
- 指定其他默认方案供授权、挑战和禁止操作使用。
- 可通过策略方案将多个方案合成一个。
身份验证处理程序
身份验证处理程序:
- 是一种实现方案行为的类型。
- 派生自 IAuthenticationHandler 或 AuthenticationHandler<TOptions>。
- 具有对用户进行身份验证的主要责任。
根据身份验证方案的配置和传入的请求上下文,身份验证处理程序:
- 构造表示用户 identity 的 AuthenticationTicket 对象(若身份验证成功)。
- 返回“无结果”或“失败”(若身份验证失败)。
- 具有用于挑战和禁止操作的方法,供用户在下述情况下访问资源时使用:
- 他们未获得访问授权(禁止)。
- 他们未经过身份验证(挑战)。
RemoteAuthenticationHandler<TOptions>
与 AuthenticationHandler<TOptions>
RemoteAuthenticationHandler<TOptions> 是需要远程身份验证步骤的身份验证类。 远程身份验证步骤完成后,处理程序将回调处理程序设置的 CallbackPath
。 处理程序使用传递给 HandleRemoteAuthenticateAsync 回调路径的信息完成身份验证步骤。 OAuth 2.0 和 OIDC 都使用此模式。 JWT 和 Cookie 不使用此模式,因为它们可以直接使用持有者标头和 cookie 进行身份验证。 在这种情况下,远程托管的提供程序:
Authenticate
身份验证方案的身份验证操作负责根据请求上下文构造用户的 identity。 它会返回一个 AuthenticateResult 指示身份验证是否成功;若成功,则在身份验证票证中指示用户的 identity。 请参阅 AuthenticateAsync。 身份验证示例包括:
- 根据 Cookie 构造用户 identity 的 cookie 身份验证方案。
- 对 JWT 持有者令牌进行反序列化和验证以构造用户 identity 的 JWT 持有者方案。
难题
当未经身份验证的用户请求要求身份验证的终结点时,授权会发起身份验证挑战。 例如,当匿名用户请求受限资源或访问登录链接时,会引发身份验证挑战。 授权会使用指定的身份验证方案发起挑战;如果未指定任何方案,则使用默认方案。 请参阅 ChallengeAsync。 身份验证挑战示例包括:
- 将用户重定向到登录页面的 cookie 身份验证方案。
- 返回具有
www-authenticate: bearer
标头的 401 结果的 JWT 持有者方案。
挑战操作应告知用户要使用哪种身份验证机制来访问所请求的资源。
禁止
当已经过身份验证的用户尝试访问其无权访问的资源时,授权会调用身份验证方案的禁止操作。 请参阅 ForbidAsync。 身份验证禁止示例包括:
- 将用户重定向到表示访问遭禁的页面的 cookie 身份验证方案。
- 返回 403 结果的 JWT 持有者方案。
- 重定向到用户可请求资源访问权限的页面的自定义身份验证方案。
用户可通过禁止操作知道:
- 他们已经过身份验证。
- 他们无权访问所请求的资源。
请查看以下链接,了解挑战与禁止之间区别:
每个租户的身份验证提供程序
ASP.NET Core 没有用于多租户身份验证的内置解决方案。 虽然客户可以使用内置功能编写一个解决方案,但建议客户考虑使用 Orchard Core 或 ABP Framework 进行多租户身份验证。
Orchard Core 是:
- 使用 ASP.NET Core 生成的开放源代码模块和多租户应用框架。
- 基于该应用框架生成的内容管理系统 (CMS)。
请参阅 Orchard Core 源,了解每个租户的身份验证提供程序的示例。
ABP Framework 支持各种体系结构模式,包括模块化、微服务、域驱动设计和多租户。 请参阅 GitHub 上的 ABP Framework 源。
其他资源
作者:Mike Rousos
身份验证是确定用户 identity 的过程。 授权是确定用户是否有权访问资源的过程。 在 ASP.NET Core 中,身份验证由身份验证服务 IAuthenticationService 负责,而它供身份验证中间件使用。 身份验证服务会使用已注册的身份验证处理程序来完成与身份验证相关的操作。 与身份验证相关的操作示例包括:
- 对用户进行身份验证。
- 在未经身份验证的用户试图访问受限资源时作出响应。
已注册的身份验证处理程序及其配置选项被称为“方案”。
身份验证方案由 Startup.ConfigureServices
中的注册身份验证服务指定:
- 方式是在调用 AddAuthentication 后调用方案特定的扩展方法(例如 AddJwtBearer 或 AddCookie)。 这些扩展方法使用 AuthenticationBuilder.AddScheme 向适当的设置注册方案。
- 不太常用的方法是直接调用
AuthenticationBuilder.AddScheme
。
例如,下列代码会为 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
。
通过调用 UseAuthentication,在 Startup.Configure
中添加身份验证中间件。 如果调用 UseAuthentication
,会注册使用之前注册的身份验证方案的中间件。 请在依赖于要进行身份验证的用户的所有中间件之前调用 UseAuthentication
。 如果使用终结点路由,则必须按以下顺序调用 UseAuthentication
:
- 在 UseRouting之后调用,以便路由信息可用于身份验证决策。
- 在 UseEndpoints 之前调用,以便用户在经过身份验证后才能访问终结点。
身份验证概念
身份验证负责提供 ClaimsPrincipal 进行授权,以针对其进行权限决策。 可通过多种身份验证方案方法来选择使用哪种身份验证处理程序负责生成正确的声明集:
- 身份验证方案
- 默认身份验证方案,将在下一节中讨论。
- 直接设置 HttpContext.User。
不会自动探测方案。 如果未指定默认方案,则必须在授权属性中指定该方案,否则将引发以下错误:
InvalidOperationException:未指定 authenticationScheme,并且未找到 DefaultAuthenticateScheme。 可使用 AddAuthentication(string defaultScheme) 或 AddAuthentication(Action<AuthenticationOptions> configureOptions) 设置默认方案。
身份验证方案
身份验证方案可选择使用哪种身份验证处理程序负责生成正确的声明集。 有关详细信息,请参阅使用特定方案授权。
身份验证方案是与下列项相对应的名称:
- 身份验证处理程序。
- 用于配置处理程序的该特定实例的选项。
方案可用作一种机制,供用户参考相关处理程序的身份验证、挑战和禁止行为。 例如,授权策略可使用方案名称来指定应使用哪种(或哪些)身份验证方案来对用户进行身份验证。 配置身份验证时,通常是指定默认身份验证方案。 除非资源请求了特定方案,否则使用默认方案。 还可:
- 指定其他默认方案供授权、挑战和禁止操作使用。
- 可通过策略方案将多个方案合成一个。
身份验证处理程序
身份验证处理程序:
- 是一种实现方案行为的类型。
- 派生自 IAuthenticationHandler 或 AuthenticationHandler<TOptions>。
- 具有对用户进行身份验证的主要责任。
根据身份验证方案的配置和传入的请求上下文,身份验证处理程序:
- 构造表示用户 identity 的 AuthenticationTicket 对象(若身份验证成功)。
- 返回“无结果”或“失败”(若身份验证失败)。
- 具有用于挑战和禁止操作的方法,供用户在下述情况下访问资源时使用:
- 他们未获得访问授权(禁止)。
- 他们未经过身份验证(挑战)。
RemoteAuthenticationHandler<TOptions>
与 AuthenticationHandler<TOptions>
RemoteAuthenticationHandler<TOptions> 是需要远程身份验证步骤的身份验证类。 远程身份验证步骤完成后,处理程序将回调处理程序设置的 CallbackPath
。 处理程序使用传递给 HandleRemoteAuthenticateAsync 回调路径的信息完成身份验证步骤。 OAuth 2.0 和 OIDC 都使用此模式。 JWT 和 Cookie 不使用此模式,因为它们可以直接使用持有者标头和 cookie 进行身份验证。 在这种情况下,远程托管的提供程序:
Authenticate
身份验证方案的身份验证操作负责根据请求上下文构造用户的 identity。 它会返回一个 AuthenticateResult 指示身份验证是否成功;若成功,则在身份验证票证中指示用户的 identity。 请参阅 AuthenticateAsync。 身份验证示例包括:
- 根据 Cookie 构造用户 identity 的 cookie 身份验证方案。
- 对 JWT 持有者令牌进行反序列化和验证以构造用户 identity 的 JWT 持有者方案。
难题
当未经身份验证的用户请求要求身份验证的终结点时,授权会发起身份验证挑战。 例如,当匿名用户请求受限资源或访问登录链接时,会引发身份验证挑战。 授权会使用指定的身份验证方案发起挑战;如果未指定任何方案,则使用默认方案。 请参阅 ChallengeAsync。 身份验证挑战示例包括:
- 将用户重定向到登录页面的 cookie 身份验证方案。
- 返回具有
www-authenticate: bearer
标头的 401 结果的 JWT 持有者方案。
挑战操作应告知用户要使用哪种身份验证机制来访问所请求的资源。
禁止
当已经过身份验证的用户尝试访问其无权访问的资源时,授权会调用身份验证方案的禁止操作。 请参阅 ForbidAsync。 身份验证禁止示例包括:
- 将用户重定向到表示访问遭禁的页面的 cookie 身份验证方案。
- 返回 403 结果的 JWT 持有者方案。
- 重定向到用户可请求资源访问权限的页面的自定义身份验证方案。
用户可通过禁止操作知道:
- 他们已经过身份验证。
- 他们无权访问所请求的资源。
请查看以下链接,了解挑战与禁止之间区别:
每个租户的身份验证提供程序
ASP.NET Core 框架没有用于多租户身份验证的内置解决方案。 虽然客户可以编写一个使用多租户身份验证的应用,但建议使用以下支持多租户身份验证的 ASP.NET Core 应用程序框架之一:
Orchard Core
Orchard Core。 请参阅 Orchard Core 源,了解每个租户的身份验证提供程序的示例。
ABP Framework
ABP Framework 支持各种体系结构模式,包括模块化、微服务、域驱动设计和多租户。 请参阅 GitHub 上的 ABP Framework 源。