Search code examples
c#asp.net-corejwtasp.net-identityidentityserver4

ASP.NET Core JWT authentication changes Claims (sub)


I have an ASP.NET Core API which uses JWT Authentication. Simple setup:

....
string authority = $"https://{configuration["Auth:Authority"]}";
string audience = configuration["Auth:Audience"];

return builder.AddJwtBearer(options =>
{
    options.Authority = authority;
    options.Audience = audience;

    options.TokenValidationParameters = new TokenValidationParameters
    {
        // NameClaimType = "http://schemas.org/email"
        // NameClaimType = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/email"
        // NameClaimType = "sub"
    };
});

(as you can see commented code, I have been trying several settings)

When I decode JWT (using jwt.io) I see there is claim "sub" in JWT and has string value (internal ID of user in dbo)

{
  "nbf": 1592585433,
  "exp": 1592585763,
  "iss": "https://*************",
  "aud": "api_10",
  "sub": "142",
  "scope": [
    "openid",
    "api_10"
  ]
}

The problem is that dotnet switch sub to name claim. This returns no (0) results:

principal.Claims.Where(w => w.Type == "sub")

This returns userId I need "142":

principal.Claims.Where(w => w.Type == ClaimTypes.Name || ClaimTypes.NameIdentifier)

What is going on?! Where is my sub claim gone?


Solution

  • Just add either JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear(); (if you're on .NET 7 or earlier) or JsonWebTokenHandler.DefaultInboundClaimTypeMap.Clear(); (for .NET 8 or later) on the API's ConfigureServices method. Its suggested on the other comment as well. I verified it on my sample repo.

    This issue is because OIDC StandardClaims are renamed on JWT token handler. By adding JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear(); you will clear the inbound claim type map on the JWT token handler.

    Read more here