在身份服务器中注册后登录

时间:2019-05-20 07:17:25

标签: identityserver4

我正在尝试在用户注册后立即登录。

下面是场景

1)注册页面不在身份服务器上。

2)将用户详细信息从用户界面发布到ID服务器以进行用户创建。

3)成功创建用户后,登录用户并重定向。

4)尝试在本机应用程序上做到这一点。

我在javascript应用程序中尝试过,但是重定向失败,出现405个选项调用。 (试图重定向到/ connect / authorize)

在移动应用上,不希望用户注册UX后再次登录。

有人实施过这种行为

benfoster之后

尝试

2 个答案:

答案 0 :(得分:2)

好吧,最后我能够使它与授权代码流一起工作

  • 每当用户注册时,就会针对新创建的用户生成并存储otp。
  • 在回复中发送此otp。
  • 在acr_value中使用此otp,例如acr_values = otp:{{otpvalue}} un:{{username}}
  • 客户端然后使用上述acr_values重定向到/ connect / authorize

下面是处理otp流的身份服务器代码

public class SignupFlowResponseGenerator : AuthorizeInteractionResponseGenerator
{
    public readonly IHttpContextAccessor _httpContextAccessor;


    public SignupFlowResponseGenerator(ISystemClock clock,
        ILogger<AuthorizeInteractionResponseGenerator> logger,
        IConsentService consent,
        IProfileService profile,
        IHttpContextAccessor httpContextAccessor)
        : base(clock, logger, consent, profile)
    {
        _httpContextAccessor = httpContextAccessor;
    }

    public override async Task<InteractionResponse> ProcessInteractionAsync(ValidatedAuthorizeRequest request, ConsentResponse consent = null)
    {
        var processOtpRequest = true;

        var isAuthenticated = _httpContextAccessor.HttpContext.User.Identity.IsAuthenticated;

        // if user is already authenticated then no need to process otp request.
        if (isAuthenticated)
        {
            processOtpRequest = false;
        }
        // here we only process only the request which have otp
        var acrValues = request.GetAcrValues().ToList();
        if (acrValues == null || acrValues.Count == 0)
        {
            processOtpRequest = false;
        }

        var otac = acrValues.FirstOrDefault(x => x.Contains("otp:"));
        var un = acrValues.FirstOrDefault(x => x.Contains("un:"));

        if (otac == null || un == null)
        {
            processOtpRequest = false;
        }

        if (processOtpRequest)
        {
            var otp = otac.Split(':')[1];
            var username = un.Split(':')[1];

            // your logic to get and check opt against the user
            // if valid then 
            if (otp == { { otp from db for user} })
            {

                // mark the otp as expired so that it cannot be used again.

                var claimPrincipal = {{build your principal}};

                request.Subject = claimPrincipal ;

                await _httpContextAccessor.HttpContext.SignInAsync({{your auth scheme}}, claimPrincipal , null);

                return new InteractionResponse
                {
                    IsLogin = false, // as login is false it will not redirect to login page but will give the authorization code
                    IsConsent = false
                };
            }
        }

        return await base.ProcessInteractionAsync(request, consent);
    }
}

别忘了在启动时添加以下代码

services.AddIdentityServer().AddAuthorizeInteractionResponseGenerator<SignupFlowResponseGenerator>()

答案 1 :(得分:0)

您可以通过使用IdentityServer4提供的IdentityServerTools类来帮助为客户端或用户(在您的情况下)发出JWT令牌

因此,在用户注册后,您已经拥有了为用户生成令牌所需的所有声明: 包括但不限于:userid,clientid,角色,声明,auth_time,aud,作用域。

如果您使用最适合移动应用程序的混合流,则很可能需要刷新令牌。

在下面的示例中,我假设您正在使用ASP.NET Identity for Users。无论您使用什么进行用户管理,IdentityServer4代码仍然适用。

public Constructor(                UserManager<ApplicationUser> userManager,
            SignInManager<ApplicationUser> signInManager,
            IClientStore clientStore,
            IdentityServerTools identityServerTools,
            IRefreshTokenService refreshTokenService)
{// minimized for clarity}

public async Task GenerateToken(ApplicationUser user
                )
            {

                var principal = await _signInManager.CreateUserPrincipalAsync(user);    
                var claims = new List<Claim>(principal.Claims);
                var client = await clientStore.FindClientByIdAsync("client_Id");
                // here you should add all additional claims like clientid , aud , scope, auth_time coming from client info
                // add client id 
                claims.Add(new Claim("client_id", client.ClientId));

                // add authtime
                claims.Add(new Claim("auth_time", $"{(Int32)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds}"));

                // add audiences
                var audiences = client.AllowedScopes.Where(s => s != "offline_access" && s != "openid" && s != "profile");
                foreach (var audValue in audiences)
                {
                    claims.Add(new Claim("aud", audValue));
                }

                // add /resources to aud so the client can get user profile info.
                var IdentityServiceSettings = _configuration.GetSection("IdentityService").Get<IdentityServiceConsumeSettings>();
                claims.Add(new Claim("aud", $"{IdentityServiceUrl}/resources"));

                //scopes for the the what cook user
                foreach (var scopeValue in client.AllowedScopes)
                {
                    claims.Add(new Claim("scope", scopeValue));
                }

                //claims.Add(new Claim("scope", ""));
                claims.Add(new Claim("idp", "local"));
                var accesstoken = identityServerTools.IssueJwtAsync(100, claims);

                var t = new Token
                {
                    ClientId = "client_id",
                    Claims = claims
                };


                var refereshToken = refreshTokenService.CreateRefreshTokenAsync(principal, t, client);

            }

这只是一个代码片段,需要根据您的情况进行一些更改