首页 > 解决方案 > 调用 HttpContext.SignInAsync 后用户退出 IdentityServer4

问题描述

这个问题之后,我有一个有趣的困境。

我已经根据 IdentityServer4 Quickstarts 构建了我的 IdentityServer。当客户端将用户定向到 IdentityServer,并且用户进行身份验证时,AccountControllerIdentityServer 上会执行 a _signInManager.PasswordSignInAsync,并且用户登录到 IdentityServer。

这可以通过打开另一个浏览器选项卡并导航到 IdentityServer 根 URL 来确认,果然,登录的用户名显示在右上角,正如预期的那样。

正如我在上面链接的问题中所解释的,然后用户被引导到一个页面,他们需要从中选择他们希望处理的租户,然后再被重定向回客户端应用程序(该交互有效)。

但是,在选择租户之后,TenantController 会调用HttpContext.SignInAsync([the currently logged-in user's subject claim value], [the selected tenant claim]),目的是重新登录已登录的用户,并传递额外的租户声明。(这是我试图让选定的 TenantId 声明出现在发送回客户端的令牌中......我愿意接受有关更好方法的建议。)

而且虽然这个交互的完成确实确实将发送给客户端的令牌中的预期用户信息传回了,但它有效地将用户从 IdentityServer 中注销?!?另一个选项卡中身份服务器根 URL 的刷新显示不再有用户登录。

为什么是这样?我究竟做错了什么?我需要用户在选择租户之前保持登录身份服务器的状态。

标签: authenticationidentityserver4

解决方案


HttpContext.SignInAsync我用标准内置 (to Microsoft.AspNetCore.Authentication)替换了 IdentityServer4 提供的扩展的使用HttpContext.SignInAsync

所以而不是:

public static async Task SignInAsync(this HttpContext context, string subject, params Claim[] claims)

来自 IdentitySever4,我用过

public static Task SignInAsync(this HttpContext context, string scheme, ClaimsPrincipal principal, AuthenticationProperties properties)

来自 Microsoft.AspNetCore.Authentication。

为了调用它,我建立了 Principal 如下:

var userId = User.Claims.Single(r => r.Type == "sub").Value;
var user = await _userManager.FindByIdAsync(userId);
var principal = await _claimsFactory.CreateAsync(user);
((ClaimsIdentity)principal.Identity).AddClaim(new Claim("TenantId", tenant.Id.ToString()));

推荐阅读