我正在尝试在用户注册后立即登录。
下面是场景
1)注册页面不在身份服务器上。
2)将用户详细信息从用户界面发布到ID服务器以进行用户创建。
3)成功创建用户后,登录用户并重定向。
4)尝试在本机应用程序上做到这一点。
我在javascript应用程序中尝试过,但是重定向失败,出现405个选项调用。 (试图重定向到/ connect / authorize)
在移动应用上,不希望用户注册UX后再次登录。
有人实施过这种行为
在benfoster之后
尝试答案 0 :(得分:2)
好吧,最后我能够使它与授权代码流一起工作
下面是处理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);
}
这只是一个代码片段,需要根据您的情况进行一些更改