我们的解决方案是复制 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 中。
Code:
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 开始)。只需选择任何其他路径即可。
- At your last step, key parts
- 我们从 cookie 中读取持久化数据
- 删除部分cookie
- 登录“真实”用户
- 重定向到 returnUrl (这已作为查询参数添加到第一步。不要忘记发送它)
In code
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 等。