使用IdentityServer3我需要在用户完成注册过程后自动登录并将本地用户重定向回客户端应用程序。有一种优雅的方式来做到这一点?从我的挖掘中我怀疑不是,在哪种情况下我可以用来实现这个目标?
我能够使用自定义User Service为外部用户实现此目的,但这使用了部分登录。但是,对于本地用户,在用户名和密码登录之前,他们不在用户服务处理的身份验证过程中。
另请注意,我无法访问用户密码,因为注册过程由多个屏幕/视图覆盖,因为在这种情况下,他们需要在注册过程中验证他们的电子邮件。
进度:
我发现了这个https://github.com/IdentityServer/IdentityServer3/issues/563,但还没有找到触发重定向的方法。
我正在尝试使用以下方式发出身份验证令牌:
var localAuthResult = userService.AuthenticateLocalAsync(user);
Request.GetOwinContext().Authentication.SignIn(new ClaimsIdentity(localAuthResult.Result.User.Claims, Thinktecture.IdentityServer.Core.Constants.PrimaryAuthenticationType));
但到目前为止我能做的最好的事情是将用户重定向回登录界面:
HttpCookie cookie = Request.Cookies["signin"]; // Stored previously at beginning of registration process
return Redirect("~/core/login?signin=" + cookie.Value);
答案 0 :(得分:14)
使用LoginPageLinks将注册链接添加到登录页面:
var authOptions = new Thinktecture.IdentityServer.Core.Configuration.AuthenticationOptions
{
IdentityProviders = ConfigureIdentityProviders,
EnableLocalLogin = true,
EnablePostSignOutAutoRedirect = true,
LoginPageLinks = new LoginPageLink[] {
new LoginPageLink{
Text = "Register",
Href = "Register"
}
}
};
使用LoginPageLinks将导致signin url参数将添加到登录页面上url的末尾。如果注册过程跨越多个页面,则需要保留此项。易于将此值存储在cookie中。
问题是注册页面必须存在于与Identity Server相同的URL下,例如"核心&#34 ;.这将允许您的页面与Identity Server共享cookie。在标准MVC控制器中,这可以使用Route装饰器来实现:
[Route("core/Register")]
[HttpGet]
[AllowAnonymous]
public ActionResult Register(string signin)
{
Response.Cookies.Add(new HttpCookie("signin", signin)); // Preserve the signin so we can use it to automatically redirect user after registration process
return View(new RegisterViewModel());
}
注册过程完成后,您可以使用IssueLoginCookie扩展方法创建登录cookie。然后,signin url参数可以与GetSignInMessage扩展方法一起使用,以检索ReturnUrl以重定向响应,该响应将自动登录用户并将其返回给客户端应用程序:
using Thinktecture.IdentityServer.Core.Extensions;
using Thinktecture.IdentityServer.Core.Models;
...
AuthenticatedLogin login = new AuthenticatedLogin()
{
IdentityProvider = Thinktecture.IdentityServer.Core.Constants.BuiltInIdentityProvider,
Subject = userId,
Name = AuthObjects.AuthUserService.GetDisplayNameForAccount(userId)
};
Request.GetOwinContext().Environment.IssueLoginCookie(login);
HttpCookie cookie = Request.Cookies["signin"];
if (cookie != null)
{
SignInMessage message = Request.GetOwinContext().Environment.GetSignInMessage(cookie.Value);
return Redirect(message.ReturnUrl);
}
else
...