authentication - 调用 HttpContext.SignInAsync 后用户退出 IdentityServer4
问题描述
继这个问题之后,我有一个有趣的困境。
我已经根据 IdentityServer4 Quickstarts 构建了我的 IdentityServer。当客户端将用户定向到 IdentityServer,并且用户进行身份验证时,AccountController
IdentityServer 上会执行 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 的刷新显示不再有用户登录。
为什么是这样?我究竟做错了什么?我需要用户在选择租户之前保持登录身份服务器的状态。
解决方案
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()));
推荐阅读
- flutter - 未处理的异常 ScrollController 未附加到任何滚动视图
- java - 内存中的非序列化对象会发生什么?
- java - 如何在fire base android中同时在一个节点的两个子节点上写入数据?
- model-view-controller - 如何在 Joomla 的前端部分使用编辑和保存按钮创建列表视图!3 成分?
- c# - 如何在 C# 中调用/编组 C++“const uint64_t*”?
- javascript - 获取销售日期可变产品 woo
- typescript - 为什么 TypeScript 接口中存在的属性会通过断言影响类型缩小,我怎样才能让它正常工作?
- vue.js - 在Vue中使用put请求编辑数组中的数组
- r - R 矢量化和 dplyr 变异错误?
- jquery - jQuery AJAX - ajax 中的变量未定义