远程身份验证

借助 System.Web 适配器的远程身份验证功能,ASP.NET Core 应用可以通过遵循 ASP.NET 应用来确定用户的标识(对 HTTP 请求进行身份验证)。 启用该功能会向 ASP.NET 应用添加一个终结点,该应用会返回一个序列化 ClaimsPrincipal,表示对终结点发出的任何请求的经过身份验证的用户。 然后,ASP.NET Core 应用会注册一个自定义身份验证处理程序,该处理程序将(为启用了远程身份验证的终结点)通过在 ASP.NET 应用上调用该终结点,并从 ASP.NET Core 应用接收的原始请求中传递所选标头和 cookie 来确定用户的标识。

配置

只需进行一些小的代码更改即可在已根据入门设置的解决方案中启用远程身份验证。

首先,按照远程应用设置说明连接 ASP.NET Core 和 ASP.NET 应用。 然后,只需调用几个额外的扩展方法即可启用远程应用身份验证。

ASP.NET 应用配置

需要配置 ASP.NET 应用以添加身份验证终结点。 通过调用 AddAuthenticationServer 扩展方法设置 HTTP 模块来监视对身份验证终结点的请求,可以添加身份验证终结点。 请注意,远程身份验证方案通常还需要添加代理支持,以便任何与身份验证相关的重定向会正确路由到 ASP.NET Core 应用,而不是 ASP.NET 应用。

SystemWebAdapterConfiguration.AddSystemWebAdapters(this)
    .AddProxySupport(options => options.UseForwardedHeaders = true)
    .AddRemoteAppServer(options =>
    {
        options.ApiKey = ConfigurationManager.AppSettings["RemoteAppApiKey"];
    })
    .AddAuthenticationServer();

ASP.NET Core 应用配置

接下来,需要将 ASP.NET Core 应用配置为启用身份验证处理程序,该处理程序将通过向 ASP.NET 应用发出 HTTP 请求来验证用户身份。 同样,这是通过在注册 System.Web 适配器服务时调用 AddAuthenticationClient 来实现的:

builder.Services.AddSystemWebAdapters()
    .AddRemoteAppClient(options =>
    {
        options.RemoteAppUrl = new Uri(builder.Configuration
            ["ReverseProxy:Clusters:fallbackCluster:Destinations:fallbackApp:Address"]);
        options.ApiKey = builder.Configuration["RemoteAppApiKey"];
    })
    .AddAuthenticationClient(true);

传递给 AddAuthenticationClient 调用的布尔值会指定远程应用身份验证是否应是默认的身份验证方案。 传递 true 将会导致针对所有请求通过远程应用身份验证对用户进行身份验证,而传递 false 则意味着仅当专门请求远程应用方案(例如,通过在控制器上的 [Authorize(AuthenticationSchemes = RemoteAppAuthenticationDefaults.AuthenticationScheme)] 或操作方法)时,才会使用远程应用身份验证对用户进行身份验证。 为此参数传递 false 的优点是仅向原始 ASP.NET 应用发出 HTTP 请求,以便对需要远程应用身份验证的终结点进行身份验证,但缺点是要求批注所有此类终结点,以指示它们将使用远程应用身份验证。

除了需要布尔值之外,还可以将可选的回调传递给 AddAuthenticationClient,以修改远程身份验证过程行为的一些其他方面:

  • RequestHeadersToForward:此属性包含在调用身份验证 API 时应从请求转发的标头。 默认情况下,转发的唯一标头是 AuthorizationCookie。 可以通过将其他标头添加到此列表来转发它们。 或者,如果列表已清理(因此未指定任何标头),则将转发所有标头。
  • ResponseHeadersToForward:此属性会列出应从身份验证请求传播回原始调用的响应标头,在标识受到质询的方案中,该原始调用会提示进行身份验证。 默认情况下,这包括 LocationSet-CookieWWW-Authenticate 标头。
  • AuthenticationEndpointPath:应发出身份验证请求的 ASP.NET 应用上的终结点。 这默认为 /systemweb-adapters/authenticate,并且必须与 ASP.NET 身份验证终结点配置中指定的终结点匹配。

最后,如果 ASP.NET Core 应用以前未包含身份验证中间件,则需要(在路由中间件之后,但在授权中间件之后)启用该中间件:

app.UseAuthentication();

设计

  1. 当 ASP.NET Core 应用处理请求时,如果远程应用身份验证是默认方案或由请求的终结点指定,则 RemoteAuthenticationAuthHandler 将尝试对用户进行身份验证。
    1. 处理程序将向 ASP.NET 应用的身份验证终结点发出 HTTP 请求。 它会将配置的标头从当前请求复制到此新请求上,以便转发与身份验证相关的数据。 如上所述,默认行为是复制 AuthorizeCookie 标头。 出于安全目的,还会添加 API 密钥标头。
  2. ASP.NET 应用将会提供发送到身份验证终结点的请求。 只要 API 密钥匹配,ASP.NET 应用就会返回序列化到响应正文中的当前用户的 ClaimsPrincipal,或者将返回 HTTP 状态代码(如 401 或 302)以及指示失败的响应标头。
  3. 当 ASP.NET Core 应用的 RemoteAuthenticationAuthHandler 接收来自 ASP.NET 应用的响应时:
    1. 如果成功返回 ClaimsPrincipal,身份验证处理程序会将其反序列化,并将其用作当前用户的标识。
    2. 如果未成功返回 ClaimsPrincipal,处理程序将存储结果,并且身份验证受到质询(例如因为用户正在访问受保护的资源),则请求的响应将更新为状态代码和来自身份验证终结点的响应的所选响应标头。 通过此操作,可将质询响应(如重定向到登录页)传播到最终用户。
      1. 由于 ASP.NET 应用的身份验证终结点的结果可能包含特定于该终结点的数据,因此用户可以将 IRemoteAuthenticationResultProcessor 实现注册到 ASP.NET Core 应用,该应用将在使用之前在任何身份验证结果上运行。 例如,内置的 IRemoteAuthenticationResultProcessorRedirectUrlProcessor,它会查找从身份验证终结点返回的 Location 响应标头,并确保它们重定向回 ASP.NET Core 应用的主机,而不是直接重定向回到 ASP.NET 应用。

已知的限制

此远程身份验证方法存在几个已知的限制:

  1. 由于 Windows 身份验证依赖于 Windows 标识的句柄,因此该功能不支持 Windows 身份验证。 未来的工作计划是探索共享 Windows 身份验证可能如何工作。 有关详细信息,请参阅dotnet/systemweb-adapters#246
  2. 借助此功能,ASP.NET Core 应用可以使用由 ASP.NET 应用进行身份验证的标识,但与用户相关的所有操作(例如登录、注销等)仍然需要通过 ASP.NET 应用进行路由。

备选方法

如果 ASP.NET 应用中的身份验证是使用 Microsoft.OwinCookie 身份验证中间件完成的,则共享标识的替代解决方案是配置 ASP.NET 和 ASP.NET Core 应用,以便它们能够共享身份验证 cookie。 共享身份验证 cookie 可支持:

  • 两个应用根据同一 cookie 确定用户标识。
  • 登录或注销一个应用可让用户登录或注销另一个应用。

请注意,由于登录通常依赖于特定的数据库,因此并非所有身份验证功能都会在两个应用中正常运行:

  • 用户应仅通过其中一个应用(ASP.NET 或 ASP.NET Core 应用)登录,无论数据库设置为使用哪哥应用。
  • 两个应用都能够查看用户的标识和声明。
  • 两个应用都能够将用户注销。

有关如何在 ASP.NET 和 ASP.NET Core 应用之间配置共享身份验证 cookie 的详细信息,请参阅cookie 共享文档System.Web 适配器 GitHub 存储库中的以下示例演示了具有支持两个应用登录和注销用户的共享 cookie 配置的远程应用身份验证:

如果以下两个条件都为 true,则共享身份验证是一个良好选项:

  • ASP.NET 应用已在使用 Microsoft.Owincookie 身份验证。
  • 可以更新 ASP.NET 应用和 ASP.NET Core 应用来使用匹配的数据保护设置。 匹配的共享数据保护设置包括共享文件路径、Redis 缓存或用于存储数据保护密钥的 Azure Blob 存储。

对于其他方案,本文档前面所述的远程身份验证方法更灵活,可能更加适合。