我们使用的是IdentityServer3,隐式授权,登录包含多个屏幕。在IdentityServer3中,内置支持这种多步登录工作流程(例如,用于接受EULA,双因素登录等),该功能称为“部分登录”,甚至还有一个示例: https://github.com/IdentityServer/IdentityServer3.Samples/tree/master/source/CustomUserService/CustomUserService
我们最近升级到AspNetCore和IdentityServer4,并想知道如何实现相同的目标?也就是说,在第一步中检查用户名和密码,如果正确,则将其安全存储(例如在加密的cookie中)以用于下一步骤。
答案 0 :(得分:8)
我们的解决方案是复制IdentityServer3的部分登录:使用自定义cookie在步骤之间保留数据。
首先,我们需要注册我们的自定义cookie身份验证(在Startup.Configure)
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationScheme = "my-partial",
AutomaticAuthenticate = false,
AutomaticChallenge = false
});
登录工作流程的第一步/入口点应映射到GET /account/login
(从IdentityServer4 1.0.0-rc2
开始)。
第二步,在发送和验证凭据后,我们会将用户名(以及最终的任何其他数据)保存到Cookie中。
代码:
var claims = new []
{
new Claim("my-user", username),
new Claim("some-attribute", someAttribute)
};
await HttpContext.Authentication
.SignInAsync("my-partial", new ClaimsPrincipal(new ClaimsIdentity(claims)));
重要:避免使用POST /account/login
作为第二步。因为无论您的结果如何,IdentityServer的中间件都会将您重定向回授权端点(从RC2开始)。只需选择任何其他路径。
代码
var partialUser = await HttpContext.Authentication.AuthenticateAsync("my-partial");
var username = partialUser?.Claims.FirstOrDefault(c => c.Type == "dr-user")?.Value;
var claims = new [] { /* Your custom claims */};
await HttpContext.Authentication
.SignOutAsync("my-partial");
await HttpContext.Authentication
.SignInAsync(username, username, claims);
return Redirect(returnUrl);
此外,您可能需要验证输入,例如,如果没有部分cookie,则返回第一步,等等。