When I make a request to my .Net Core 2 API from my Angular app the JWT is not the same as the one sent in the request header.
Startup.cs
I have figured out part of my problem.
I was wrong in saying the token coming from the UI was different than what the .net API was receiving. I said I was inspecting the Header in the Network tab, and I was, but just not the correct request. My UI was sending several requests - from different Angular modules. I was injecting a new authentication service (where my token is stored) in each module. On logout, not ever module was getting refreshed, so those that were not kept their old copy of the token. Therefore, upon login, only the affected modules (in my case, my main app.module.ts
) were getting refreshed. The ones that had not been touched kept their same copy of the authentication service.
I removed the injection from each module and let them inherit from the main app.module.ts
That fixed the issue of the UI and API appearing to have different tokens.
The other issue I mentioned of not being able to see the nameid
claim is partially resolved. I have a total of 10 Claims
inside User
. When I decode the JWT it says I have sub
and nameid
. However, when I inspect Claims
in my UserService.cs
they are not listed as nameid
and sub
, but rather http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier
and http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier
. Each have the correct Value
. I am not sure where or how this happens. I created the following custom middleware code to see what the token was when coming in and it has the Claim
as sub
and nameid
.
app.Use(async (context, next) =>
{
var authHeader = context.Request.Headers["Authorization"].ToString();
if (authHeader != null && authHeader.StartsWith("bearer", StringComparison.OrdinalIgnoreCase))
{
var tokenStr = authHeader.Substring("Bearer ".Length).Trim();
System.Console.WriteLine(tokenStr);
var handler = new JwtSecurityTokenHandler();
var token = handler.ReadToken(tokenStr) as JwtSecurityToken;
var nameid = token.Claims.First(claim => claim.Type == "nameid").Value;
var identity = new ClaimsIdentity(token.Claims);
context.User = new ClaimsPrincipal(identity);
}
await next();
});
So, the variable nameid
is right and contains the expected value. Somewhere along the line the Type
is changing from nameid
and sub
to http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier
Faced with same issue with sub
changing to http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier
, found answer in https://stackoverflow.com/a/62881110/11593686.
But also, managed to solve the issue myself:
I've checked that resulting token contains sub
, so it gets transformed when reading/validating, so I just:
var tokenHandler = new JwtSecurityTokenHandler();
//otherwise `sub` (and some other claims) get changed to ClaimTypes.NameIdentifier
tokenHandler.InboundClaimTypeMap = tokenHandler.OutboundClaimTypeMap;
i.e. copied Outbound map to Inbound map, so they are equal.