How to do multiple-step login in IdentityServer4?

戏子无情 提交于 2019-12-21 02:35:14

问题


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 (for example for accepting EULA, two-factor login, etc.), The feature called "partial login" and there is even an example: https://github.com/IdentityServer/IdentityServer3.Samples/tree/master/source/CustomUserService/CustomUserService

We've recently upgraded to AspNetCore and IdentityServer4 and wondering how suppose to achieve the same? That is, check username and password in the first step, and if correct, store it securely (for example in an encrypted cookie) for the next step(s).


回答1:


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.



来源:https://stackoverflow.com/questions/40609585/how-to-do-multiple-step-login-in-identityserver4

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!