首页 > 解决方案 > 在 ASP.NET Core 上配置 DefaultScheme 和 DefaultChallengeScheme 有什么意义?

问题描述

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

ConfigureService客户端应用程序上的方法如下。在这里,我对DefaultSchemeand感到困惑DefaultChallengeScheme。配置这些有什么意义?如果可能的话,关于它如何工作的详细描述将非常有帮助。

我已经看到了,而不是DefaultScheme,DefaultSignInScheme也可以,但是它是如何工作的?那些有什么区别?

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;
    });
}

标签: c#asp.net-coreidentityserver4asp.net-authentication

解决方案


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

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

身份验证操作

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

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

    例如,cookie 认证方案使用 cookie 数据来恢复用户身份。或者,JWT Bearer 身份验证方案将使用作为请求标头的一部分提供的令牌Authorization来创建用户身份。

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

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

  • 登录:当一个身份验证方案被登录时,该方案被告知获取一个现有用户 (a ClaimsPrincipal) 并以某种方式保持该用户。例如,在 cookie 身份验证方案上登录用户基本上会创建一个包含该用户身份的 cookie。

  • 注销:这与登录相反,基本上会告诉身份验证方案删除该持久性。退出 cookie 方案将有效地使 cookie 过期。

请注意,并非所有身份验证方案都可以执行所有选项。登录和注销通常是特殊操作。cookie 身份验证方案是一个支持登录和注销的示例,但 OIDC 方案无法做到这一点,而是依赖不同的方案来登录和持久化身份。这就是为什么您通常也会看到 cookie 方案。

典型的身份验证流程

可以显式使用身份验证方案。例如,当您在 上使用其中一种身份验证扩展方法时HttpContexthttpContext.AuthenticateAsync(),您始终可以明确指定要用于此操作的身份验证方案。

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

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

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

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

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

  • 验证: DefaultAuthenticateScheme, 或DefaultScheme
  • 挑战:DefaultChallengeScheme,或DefaultScheme
  • 禁止:DefaultForbidScheme, 或DefaultChallengeScheme, 或DefaultScheme
  • 登录: DefaultSignInScheme, 或DefaultScheme
  • 登出: DefaultSignOutScheme, 或DefaultScheme

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

您的示例很好地说明了这一点:使用 OIDC,您将需要一个登录方案,该方案可以保留由外部身份验证提供程序提供的身份。所以你通常会看到 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 提供商,以便他们可以在那里登录并返回身份。所以我们将默认的挑战方案设置为 OIDC 方案。

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


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


推荐阅读