Auth0 Home Blog Docs

Access Token doesn't contain a `sub` claim

jwt
api
access-token

#1

I have a React Native app whcih is using the Auth0 lib and authenticating via a call to the following:

auth0.webAuth.authorize({
  scope: "openid profile email",
  audience: `api.identifier`,
  prompt: "login"
})

As expected, this opens a browser where I enter my username and password. I’m then returned an object which looks like this:

{
  accessToken: "_accessTokenContent_",
  expiresIn: 86400,
  idToken: "_idTokenContent_",
  tokenType: "Bearer"
}

I then use the access token to make calls to my ASP.Net Core API, which is configured based on the quickstart. This works in as much as the access token is accepted and the User.Identity.IsAuthenticated is true. However the User.Claims enumerable doesn’t contain a sub claim and (I think) this leads to User.Identity.Name being null. The claims which are available are the following (note there are 2 aud claims, that isn’t a typo):

The http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier claim contains what I would expect the sub claim to contain (i.e. the auth0 user id) so it’s not a huge problem because I can “map” that claim to User.Identity.Name like so (within startup.cs):

options.TokenValidationParameters = new TokenValidationParameters
{
  NameClaimType = ClaimTypes.NameIdentifier
};

That being said, I’d like to know if I’ve done something wrong along the way which has meant sub isn’t available on the access token?


#2

By default, the JwtSecurityTokenHandler, which is used by the JwtBearerAuthentication middleware to process the token, does some claim mapping when constructing the ClaimsPrincipal that you get in the User property. Among that default mapping, sub claim is mapped to the ClaimTypes.NameIdentifier as seen here: https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/blob/6e7a53e241e4566998d3bf365f03acd0da699a31/src/System.IdentityModel.Tokens.Jwt/ClaimTypeMapping.cs#L59.

So, this is expected, you aren’t doing anything wrong :slight_smile:

By setting the NameClaimType in the TokenValidationParameters:

options.TokenValidationParameters = new TokenValidationParameters
{
  NameClaimType = ClaimTypes.NameIdentifier
};

you are indicating that the ClaimsIdentity constructed will have the name identifier claim as NameClaimType, the claim used to extract the name of the user, instead of the default ClaimsTypes.Name (which is by default not available in the Access Token).
Identity.Name is a simple shortcut to find the first claim whose type matches what’s set for the identity’s NameClaimType property.

Additional note: you are getting two aud (audience) claims because you most likely ask for a token that had both an audience indicating your own API identifier and also used the openid scope. This results in Auth0 issuing an access token that is valid both for your API and the https://{your_auth0_domain}/userinfo OpenID Connect user info endpoint (hence the two “audiences”).


#3

Thanks Nicolas.

Just so I understand fully, you’re saying that it’s expected that I’m not seeing a ‘sub’ claim?

Are you saying that the ‘sub’ claim does exist on the access token but is mapped to the ‘ClaimTypes.NameIdentifier’ (and then removed?) by the middleware?

Thanks for the additional clarification on the ‘aud’ claims too :+1:

Cheers,
Lee


#4

Exactly.
The sub exists in the token but the middleware is mapping (renaming) sub as the claim type string to http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier (the constant defined in ClaimTypes.NameIdentifier).

If you can get the token raw string you can inspect its contents at https://jwt.io.


#5

Great, thanks for clarifying Nicolas. Much appreciated!