How to do multiple-step login in IdentityServer4?

后端 未结 1 2008
一整个雨季
一整个雨季 2020-12-31 20:48

We were using IdentityServer3, implicit grant and the login consists of multiple screen. In IdentityServer3, there\'s built in support for such multiple step login workflow

相关标签:
1条回答
  • 2020-12-31 21:43

    Our solution was to replicate the IdentityServer3's partial login: use a custom cookie to persist data between steps.

    First, we need to register our custom cookie authentication (at Startup.Configure)

    app.UseCookieAuthentication(new CookieAuthenticationOptions
    {
        AuthenticationScheme = "my-partial",
        AutomaticAuthenticate = false,
        AutomaticChallenge = false
    });
    
    1. The first step/entry point of the login workflow should be mapped to GET /account/login (as of IdentityServer4 1.0.0-rc2).

    2. In second step, after the credentials are sent and verified, we persist the username (and eventually any other data) into a 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)));
    

    Important: avoid using POST /account/login as a second step. Because regardless of your result, IdentityServer's middleware will redirect you back to the authorization endpoint (as of RC2). Just pick any other path.

    1. At your last step, key parts
      • we read the persisted data from the cookie
      • remove the partial cookie
      • sign in the "real" user
      • redirect to returnUrl (this was added to the first step as a query parameter. Don't forget to send along it)

    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);
    

    In addition, you might want to validate inputs, for example return to the first step, if there is no partial cookie, etc.

    0 讨论(0)
提交回复
热议问题