Question

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

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'?

 46  31012  46
1 Jan 1970

Solution

 39
  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 ClaimTypes.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

2020-05-19

Solution

 25

Nan Yu's answer no longer works as of .NET 8 Preview 7. I think the idiomatic way to do it since then is to set JwtBearerOptions.MapInboundClaims to false in the call to AuthenticationBuilder.AddJwtBearer.


            services
                .AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
                .AddJwtBearer(jwtBearerOptions =>
                {
                    jwtBearerOptions.MapInboundClaims = false;
                });

Alternatively, in spirit of the old method, just change JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear(); to JsonWebTokenHandler.DefaultInboundClaimTypeMap.Clear();

See discussion in this GitHub issue.

2023-08-14