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

时间:2019-09-18 17:45:59

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

使用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);

}

我得到了所有claims,但id为空...

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

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

3 个答案:

答案 0 :(得分:1)

  1. 要不让Microsoft Identity覆盖声明名称,必须在API启动JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();之前使用app.UseAuthentication()

  2. 使用直接的“ sub”声明代替ClaimThypes.NameIdentifier,例如 var id = this.User.FindFirstValue("sub");

有关更多参考,请参见有关它的详细讨论: https://github.com/IdentityServer/IdentityServer4/issues/2968#issuecomment-510996164

答案 1 :(得分:0)

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

JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();

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

JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();

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

答案 2 :(得分:0)

静态字符串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开发人员都在哀叹这是纯粹出于遗留原因而存在的邪恶。)