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

Ama*_*ika 8 c# asp.net-authentication asp.net-core identityserver4

我正在学习ASP.NET Core 2.0和IdentityServer4上的安全性.我使用IdentityServer,Api和ASP.NET MVC Client App设置项目.

ConfigureServiceClient App上的方法如下所示.在这里,我的困惑DefaultSchemeDefaultChallegeScheme.配置那些有什么意义?如果可能的话,关于它如何工作的详细描述将非常有用.

我已经看到了DefaultScheme,DefaultSignScheme但也有效,但它是如何工作的?这些有什么区别?

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;
    });
}
Run Code Online (Sandbox Code Playgroud)

pok*_*oke 27

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

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

验证操作

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

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

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

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

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

  • 登录:当登录身份验证方案时,系统会告知该方案采用现有用户(a ClaimsPrincipal)并以某种方式保留该方案.例如,在cookie身份验证方案中签署用户将基本上创建包含该用户身份的cookie.

  • 注销:这是登录的反向,基本上会告诉身份验证方案删除该持久性.注销cookie方案将有效地使cookie过期.

请注意,并非所有身份验证方案都可以执行所有选 登录和注销通常是特殊操作.cookie身份验证方案是支持登录和退出的示例,但OIDC方案例如不能这样做,但将依赖于不同的方案来登录并保持身份.这就是为什么你通常也会看到它的cookie方案.

典型的认​​证流程

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

因此,例如,如果您想使用cookie身份验证方案登录,则"Cookie"只需从代码中调用它:

 var user = new ClaimsPrincipal(…);
 await httpContext.SignInAsync(user, "Cookie");
Run Code Online (Sandbox Code Playgroud)

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

这就是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;
});
Run Code Online (Sandbox Code Playgroud)

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

例外情况是挑战身份验证时:在这种情况下,我们希望将用户重定向到OIDC提供程序,以便他们可以登录并返回身份.因此,我们将默认挑战方案设置为OIDC方案.

此外,我们还将OIDC计划与cookie方案联系起来.当用户受到质疑并使用其外部身份验证提供程序登录时,他们将以其外部身份发送回Web应用程序.OIDC方案虽然不能保持这种身份,但它使用不同的方案 - cookie方案 - 然后代表OIDC方案持久保存身份.因此,cookie方案将为OIDC标识创建一个cookie,并且在下一个请求中,cookie方案(这是默认方案)将能够使用该cookie再次验证用户.


所以大多数的时候,你会被罚款只指定默认方案,然后根据您的身份验证设置可能改变一个或两个明确的行动.但理论上,你完全可以设置不同的默认值和多方案的一个非常复杂的设置:该框架为您提供了很大的灵活性在这里.

  • 感谢您回答戳。这将有助于许多其他试图理解深度的人。 (4认同)
  • 我错过了有关此类身份验证的更多解释。很棒的信息。 (3认同)
  • @PavelVoronin 你是对的,无参数的 `AddAuthentication()` 不会配置_如何_使用方案。然而,有一些用例:有时,您不需要默认的身份验证方案,例如,如果您总是显式调用它或通过授权策略强制执行它。您还可以多次调用`AddAuthentication()`。例如,如果您有一些实用程序方法想要添加额外的身份验证方案,它们可以轻松完成,而无需配置默认值。您不需要在同一调用中配置它,这主要是为了方便。 (2认同)