【问题标题】:Why is ClaimTypes.NameIdentifier not mapping to 'sub'?为什么 ClaimTypes.NameIdentifier 没有映射到“sub”?
【发布时间】:2020-01-19 17:39:04
【问题描述】:

使用 ASP.NET Core 2.2 和 Identity Server 4 我有以下控制器:

[HttpGet("posts"), Authorize]
public async Task<IActionResult> GetPosts() {

  var authenticated = this.User.Identity.IsAuthenticated;

  var claims = this.User.Identities.FirstOrDefault().Claims;

  var id = this.User.FindFirstValue(ClaimTypes.NameIdentifier);

}

我得到了所有的claimsid 是空的......

我检查了 claims 中的所有值,并且我有一个值为 1 的“子”声明。

为什么 ClaimTypes.NameIdentifier 没有映射到“sub”?

【问题讨论】:

  • 尝试设置:JwtSecurityTokenHandler.DefaultMapInboundClaims = false;这主要是为了解决 sub 声明被转换为 nameidentifier 声明的事实。
  • 它没有解决它... id 仍然为空。
  • 这是一个很好的问题,这就是为什么我支持它(现在从 -1 到 0),但你的例子与你的问题无关。如果您在声明中看到“sub”,则 FindFirstValue of “sub”。

标签: c# asp.net-core identityserver4 asp.net-core-2.2


【解决方案1】:

我假设在 OIDC 配置中,您已使用以下命令清除 Microsoft JWT 令牌处理程序上的入站声明类型映射:

JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();

然后您可以手动设置声明sub 的声明类型映射:

JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();

JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Add("sub", ClaimTypes.NameIdentifier);

【讨论】:

  • 我尝试了你的建议,但仍然无效......不知道发生了什么......
  • 如果你删除这一行怎么办:JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
  • 调用 Clear 我得到错误 'System.ArgumentException' in System.Private.CoreLib.dll: 'An item with the same key has already been added. Key: sub'
  • 尝试删除这一行:JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();,还有这一行JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Add("sub", ClaimTypes.NameIdentifier);,删除两个代码
  • 非常感谢...当其他问题出现 DefaultInboundClaimTypeMap.Clear() 时,您的代码添加 NameIdentifier 声明类型
【解决方案2】:

静态字符串ClaimTypes.NameIdentifier具有以下值:http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier

难怪它不能用于查找sub 声明的值。

如果您知道 sub 声明包含用户 ID,则只需使用 sub 字符串进行查找。

ClaimTypes.NameIdentifier 仅在 ClaimsPrincipal 是使用默认入站声明类型映射创建的情况下查找用户 ID,该映射将 sub 声明映射到 http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier

但即使在这种情况下,使用userManager.Options.ClaimsIdentity.UserIdClaimType 更合适,因为这是原始映射中使用的实际值(默认为ClaimTypes.NameIdentifier,但可以自定义)。

(但是,是的,整个映射非常混乱,并且有许多 Github 问题打开,甚至 MS 开发人员都感叹这是一个仅出于遗留原因而存在的邪恶。)

【讨论】:

    【解决方案3】:
    1. 为了不让 Microsoft Identity 覆盖声明名称,您必须在 API 启动中的 app.UseAuthentication() 之前使用 JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();

    2. 使用直接“子”声明而不是 ClaimThypes.NameIdentifier 例如 var id = this.User.FindFirstValue("sub");

    如需进一步参考,请参阅有关它的详细讨论: https://github.com/IdentityServer/IdentityServer4/issues/2968#issuecomment-510996164

    【讨论】:

    • 这应该被标记为正确答案。
    猜你喜欢
    • 2016-02-05
    • 2013-10-07
    • 2023-03-31
    • 1970-01-01
    • 2017-03-07
    • 1970-01-01
    • 1970-01-01
    • 2017-01-13
    相关资源
    最近更新 更多