在 ASP.NET Core 上配置 DefaultScheme 和 DefaultChallengeScheme 有什么意义?

What is the point of configuring DefaultScheme and DefaultChallengeScheme on ASP.NET Core?

我正在学习安全性如何在 ASP.NET Core 2.0 和 IdentityServer4 上工作。我使用 IdentityServer、API 和 ASP.NET Core MVC 客户端应用程序设置项目。

ConfigureService 客户端应用程序上的方法,如下所示。在这里,我对 DefaultSchemeDefaultChallengeScheme 感到困惑。配置这些有什么意义?如果可能的话,详细描述它是如何工作的会很有帮助。

我已经看到 DefaultSchemeDefaultSignInScheme 也可以,但它是如何工作的?它们有什么区别?

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc();
    JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();

    services.AddAuthentication(options =>
    {
        options.DefaultScheme = "Cookies";
        options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
        //options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
        //options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
    })
    .AddCookie("Cookies")
    .AddOpenIdConnect(OpenIdConnectDefaults.AuthenticationScheme, options =>
    {
        options.SignInScheme = "Cookies";
        options.RequireHttpsMetadata = false;

        options.Authority = "http://localhost:5000/";
        options.ClientId = "mvcclient";
        options.SaveTokens = true;
    });
}

首先请注意,您没有在那里使用 ASP.NET Core Identity。身份是在身份验证系统之上构建的用户管理堆栈。您似乎将 OpenID Connect 与 IdentityServer 作为提供者一起使用,因此您的 Web 应用程序将仅使用 OIDC 信息,而不必管理自己的身份(虽然 IdentityServer 可能正在使用 ASP.NET Core Identity ).

认证栈在ASP.NETCore中的工作方式是你可以配置一组认证方案。其中一些方案需要组合使用,例如 cookie 身份验证方案很少单独使用,但也有一些方案可以完全单独使用(例如 JWT Bearer 身份验证)。

身份验证操作

在身份验证领域,您可以执行某些操作:

  • Authenticate:进行身份验证基本上意味着使用给定的信息并尝试使用该信息对用户进行身份验证。因此,这将尝试创建 用户身份并使其可用于框架。

    例如cookie认证方案就是利用cookie数据来还原用户身份。或者 JWT Bearer 身份验证方案将使用作为请求中 Authorization header 的一部分提供的令牌来创建用户身份。

  • Challenge:当身份验证方案受到挑战时,该方案应提示用户对自己进行身份验证。例如,这可能意味着用户被重定向到登录表单,或者将被重定向到外部身份验证提供程序。

  • Forbid:当一个认证方案被禁止时,该方案基本上只是用一些东西来回应,告诉用户他们不能做他们试图做的任何事情.这通常是 HTTP 403 错误,可能是重定向到某个错误页面。

  • Sign-in:登录身份验证方案时,系统会通知该方案接受现有用户(ClaimsPrincipal) 并以某种方式坚持这一点。例如,在 cookie 身份验证方案上登录用户基本上会创建一个包含该用户身份的 cookie。

  • Sign-out:这与sign-in相反,基本上会告诉身份验证方案删除该持久性。注销 cookie 方案将使 cookie 有效失效。

Note that not all authentication schemes can perform all options. Sign-in and sign-out are typically special actions. The cookie authentication scheme is an example that supports signing in and out, but the OIDC scheme for example cannot do that but will rely on a different scheme to sign-in and persist the identity. That’s why you will usually see the cookie scheme with it as well.

典型的身份验证流程

可以显式使用身份验证方案。当您使用 authentication extension methods on the HttpContext, for example httpContext.AuthenticateAsync() 之一时,您始终可以明确指定要用于此操作的身份验证方案。

因此,例如,如果您想要使用 cookie 身份验证方案 "Cookie" 登录,您可以简单地从您的代码中这样调用它:

 var user = new ClaimsPrincipal(…);
 await httpContext.SignInAsync(user, "Cookie");

但实际上,像那样直接明确地调用身份验证并不是最常见的做法。相反,您通常会依赖框架为您进行身份验证。为此,框架需要知道哪种身份验证方案用于哪种操作。

这就是 AuthenticationOptions 的用途。您可以配置这些选项,以便您可以明确定义要用作每个身份验证操作的默认身份验证方案:

您通常不会配置 所有 这些属性。相反,该框架有一些默认的回退,因此您可以只配置这些属性的一个子集。逻辑是这样的:

  • 验证:DefaultAuthenticateScheme,或DefaultScheme
  • 挑战:DefaultChallengeScheme,或DefaultScheme
  • 禁止:DefaultForbidScheme,或DefaultChallengeScheme,或DefaultScheme
  • Sign-in:DefaultSignInScheme,或DefaultScheme
  • Sign-out:DefaultSignOutScheme,或DefaultScheme

如您所见,如果未配置特定操作的默认值,则每个身份验证操作都会回退到 DefaultScheme。因此,您通常会看到正在配置的 DefaultScheme,然后为需要不同方案的那些配置特定操作。

您的示例很好地说明了这一点:使用 OIDC,您将需要一个 sign-in 方案来保留外部身份验证提供商提供的身份。所以你通常会看到OIDC和cookie认证方案:

services.AddAuthentication(options =>
{
    options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOpenIdConnect(options =>
{
    options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
});

对于用户来说,正常的交互是通过 cookie 身份验证方案:当他们访问 Web 应用程序时,cookie 身份验证方案将尝试使用他们的 cookie 对他们进行身份验证。所以使用cookie认证方案作为所有操作的默认方案。

例外情况是在挑战身份验证时:在这种情况下,我们希望将用户重定向到 OIDC 提供商,这样他们就可以在那里登录并 return 使用身份。所以我们设置默认的challenge方案为OIDC方案

此外,我们还link OIDC方案与cookie方案。当用户受到挑战并使用其外部身份验证提供程序登录时,他们将使用其外部身份被发送回 Web 应用程序。不过,OIDC 方案无法保留该身份,因此它使用 使用 不同的方案(cookie 方案)登录,然后该方案将代表 OIDC 方案保留身份。因此 cookie 方案将为 OIDC 身份创建一个 cookie,并且在下一次请求时,cookie 方案(默认方案)将能够使用该 cookie 再次对用户进行身份验证。


所以大多数时候,您只需指定默认方案就可以了,然后根据您的身份验证设置可能会更改一两个显式操作。但从理论上讲,您完全可以设置不同默认值和多种方案的非常复杂的设置:该框架在这里为您提供了很大的灵活性。