Why is ClaimTypes.NameIdentifier not mapping to 'sub'?

冷暖自知 提交于 2021-02-18 22:07:25

问题


Using ASP.NET Core 2.2 and Identity Server 4 I have the following controller:

[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);

}

I get all the claims but id is null ...

I checked all values in claims and I have a 'sub' claim with value 1.

Why is ClaimTypes.NameIdentifier not mapping to 'sub'?


回答1:


  1. To not let Microsoft Identity to override claim names you have to use JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear(); just before the app.UseAuthentication() in the API startup.

  2. Use direct "sub" claim instead of ClaimThypes.NameIdentifier e.g. var id = this.User.FindFirstValue("sub");

For further reference please see detailed discussion on it: https://github.com/IdentityServer/IdentityServer4/issues/2968#issuecomment-510996164




回答2:


I assume in OIDC configuration you have clear the inbound claim type map on the Microsoft JWT token handler with :

JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();

You can then manually setting the claim type mapping for claim sub:

JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();

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



回答3:


The static string ClaimTypes.NameIdentifier has the following value: http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier

So no wonder it can't be used to look up the value of the sub claim.

If you know that the sub claim contains the user id, you can just do the lookup simply with the sub string.

ClaimTypes.NameIdentifier works for looking up the user id only in cases when the ClaimsPrincipal was created with the default inbound claim type mapping, which maps the sub claim to http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier.

But even in such cases it's more appropriate to use userManager.Options.ClaimsIdentity.UserIdClaimType, because this is the actual value used in the original mapping (which defaults to ClaimTypes.NameIdentifier, but can be customized).

(But yes, this whole mapping is quite confusing, and there are a number of Github issues opened where even MS devs lament that this is an evil existing solely for legacy reasons.)



来源:https://stackoverflow.com/questions/57998262/why-is-claimtypes-nameidentifier-not-mapping-to-sub

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!