如何在IdentityServer4中进行多步登录?

时间:2016-11-15 12:13:30

标签: login oauth-2.0 asp.net-core identityserver3 identityserver4

我们使用的是IdentityServer3,隐式授权,登录包含多个屏幕。在IdentityServer3中,内置支持这种多步登录工作流程(例如,用于接受EULA,双因素登录等),该功能称为“部分登录”,甚至还有一个示例: https://github.com/IdentityServer/IdentityServer3.Samples/tree/master/source/CustomUserService/CustomUserService

我们最近升级到AspNetCore和IdentityServer4,并想知道如何实现相同的目标?也就是说,在第一步中检查用户名和密码,如果正确,则将其安全存储(例如在加密的cookie中)以用于下一步骤。

1 个答案:

答案 0 :(得分:8)

我们的解决方案是复制IdentityServer3的部分登录:使用自定义cookie在步骤之间保留数据。

首先,我们需要注册我们的自定义cookie身份验证(在Startup.Configure)

app.UseCookieAuthentication(new CookieAuthenticationOptions
{
    AuthenticationScheme = "my-partial",
    AutomaticAuthenticate = false,
    AutomaticChallenge = false
});
  1. 登录工作流程的第一步/入口点应映射到GET /account/login(从IdentityServer4 1.0.0-rc2开始)。

  2. 第二步,在发送和验证凭据后,我们会将用户名(以及最终的任何其他数据)保存到Cookie中。

  3. 代码:

    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开始)。只需选择任何其他路径。

    1. 在最后一步,关键部分
      • 我们从Cookie
      • 中读取了持久数据
      • 删除部分Cookie
      • 登录“真实”用户
      • 重定向到returnUrl(这是作为查询参数添加到第一步。不要忘记发送它)
    2. 代码

      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,则返回第一步,等等。