我正在学习安全性如何在ASP.NET Core 2.0和IdentityServer4上工作。我使用IdentityServer,Api和ASP.NET MVC客户端应用程序设置了项目。
客户端应用程序上的 ConfigureService
方法如下。在这里,我对DefaultScheme
和DefaultChallegeScheme
感到困惑。配置这些的重点是什么?如果可能的话,对其进行详细的描述将非常有帮助。
我已经看到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;
});
}
答案 0 :(得分:12)
首先请注意,您在那里没有使用ASP.NET Core Identity。身份是在身份验证系统的顶部构建的用户管理堆栈。您似乎正在将OpenID Connect与IdentityServer作为提供程序一起使用,因此您的Web应用程序将仅使用OIDC信息,而不必管理自己的身份(尽管IdentityServer可能使用ASP.NET Core身份)。
身份验证堆栈在ASP.NET Core中的工作方式是可以配置一组身份验证方案。这些方案中的某些方案打算结合使用,例如cookie身份验证方案很少单独使用,但也有一些方案可以完全分开使用(例如JWT Bearer身份验证)。
在身份验证世界中,您可以执行某些操作:
身份验证:基本上,身份验证意味着使用给定的信息,并尝试使用该信息对用户进行身份验证。因此,这将尝试创建用户身份并将其用于框架。
例如,cookie身份验证方案使用cookie数据来还原用户身份。否则,JWT Bearer身份验证方案将使用请求中Authorization
标头中提供的令牌来创建用户身份。
挑战:挑战身份验证方案时,该方案应提示用户进行身份验证。例如,这可能意味着用户将重定向到登录表单,或者将重定向到外部身份验证提供程序。
禁止:当禁止身份验证方案时,该方案基本上只是以某种响应来告知用户,他们可能不会做任何尝试做的事情。这通常是HTTP 403错误,并且可能是重定向到某些错误页面。
登录:登录身份验证方案时,系统会告知该方案采用现有用户(ClaimsPrincipal
)并将其保留在某种方式。例如,使用Cookie身份验证方案登录用户基本上会创建一个包含该用户身份的Cookie。
退出:这是登录的相反过程,基本上可以告诉认证方案删除该持久性。退出cookie方案将使cookie有效。
请注意,并非所有身份验证方案都可以执行所有选项。登录和注销通常是特殊操作。 cookie身份验证方案是一个支持登录和注销的示例,但是OIDC方案例如不能这样做,而是将依赖于其他方案来登录并保留身份。这就是为什么您通常也会看到带有cookie方案的原因。
身份验证方案可以显式使用。当您使用authentication extension methods on the HttpContext
中的一个,例如httpContext.AuthenticateAsync()
时,则始终可以显式指定要用于此操作的身份验证方案。
例如,如果您想使用cookie身份验证方案"Cookie"
登录,则可以从代码中简单地这样调用它:
var user = new ClaimsPrincipal(…);
await httpContext.SignInAsync(user, "Cookie");
但是在实践中,最直接的事情就是直接直接地进行身份验证。取而代之的是,您通常将依靠该框架为您执行身份验证。为此,框架需要知道对哪种操作使用哪种身份验证方案。
这就是AuthenticationOptions
的作用。您可以配置这些选项,以便可以明确定义将哪种身份验证方案用作这些身份验证操作的默认身份验证:
DefaultAuthenticateScheme
:设置身份验证时使用的默认方案。DefaultChallengeScheme
:设置挑战时使用的默认方案。DefaultForbidScheme
:设置禁止访问时使用的默认方案。DefaultSignInScheme
:设置默认的登录方案。DefaultSignOutScheme
:设置默认方案以退出。DefaultScheme
:设置默认的后备方案(请参见下文)。您通常不配置 all 所有这些属性。相反,该框架具有一些默认的后备,因此您可以仅配置这些属性的一部分。逻辑是这样的:
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再次验证用户的身份。
因此,在大多数情况下,只需指定默认方案即可,然后根据身份验证设置可能更改一个或两个显式操作即可。但是从理论上讲,您可以完全设置一个非常复杂的设置,包括不同的默认值和多种方案:该框架为您提供了很大的灵活性。