.Net Core API JWT Token Validation
Asked Answered
B

2

7

Implemented the JWT Bearer Token validation in .Net Core WEB API as mentioned below:

 services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
                .AddJwtBearer(opt =>
                {
                    opt.Audience = Configuration["AAD:ResourceId"];
                    opt.Authority = $"{Configuration["AAD:Instance"]}{Configuration["AAD:TenantId"]}";
                });

Doubt here is the above mentioned code will validate only the audience and authority ? or it will validate all the parameters like expiration and signature etc. ?

Do we need to validate the signature explicitly to check the payload has been tampered ?

Burthen answered 31/3, 2021 at 15:57 Comment(1)
Based on my experience it is validating both expiration and signature, but the docs are not that clear: JWT bearer authentication performs authentication by extracting and validating a JWT token from the Authorization request header.Mallarme
M
11

I think you're looking for this:

https://zhiliaxu.github.io/how-do-aspnet-core-services-validate-jwt-signature-signed-by-aad.html

Here zhiliaxu explains in details how and what is actually validated when using .AddJwtBearer() and their conclusions are:

Now it is clear that

  • JWT signature is validated without providing any key or certification in our service’s source code.
  • JWT signing key is retrieved from the well-known URL https://login.microsoftonline.com/common/discovery/keys, based on JwtBearerOptions.Authority property.
  • The signing key is cached in the JwtBearerHandler singleton instance, and so our ASP.NET Core service only needs to retrieve it once throughout its lifecycle.

Also based on this article we can take a look at the ValidateToken() documentation on MSDN: https://learn.microsoft.com/en-us/dotnet/api/system.identitymodel.tokens.jwt.jwtsecuritytokenhandler.validatetoken?view=azure-dotnet Where you can find the different exceptions the method throws:

  • SecurityTokenDecryptionFailedException: token was a JWE was not able to be decrypted.
  • SecurityTokenEncryptionKeyNotFoundException: token 'kid' header claim is not null AND decryption fails.
  • SecurityTokenException: token 'enc' header claim is null or empty.
  • SecurityTokenExpiredException: token 'exp' claim is < DateTime.UtcNow.
  • SecurityTokenInvalidAudienceException: token 'aud' claim did not match either ValidAudience or one of ValidAudiences.
  • SecurityTokenInvalidLifetimeException: token 'nbf' claim is > 'exp' claim.
  • SecurityTokenInvalidSignatureException: token.signature is not properly formatted.
  • SecurityTokenNoExpirationException: TokenReplayCache is not null and expirationTime.HasValue is false. When a TokenReplayCache is set, tokens require an expiration time.
  • SecurityTokenNotYetValidException: token 'nbf' claim is > DateTime.UtcNow.
  • SecurityTokenReplayAddFailedException: token could not be added to the TokenReplayCache.
  • SecurityTokenReplayDetectedException: token is found in the cache.
Mallarme answered 31/3, 2021 at 16:31 Comment(2)
Getting the following error while API getting called: IDX10501: Signature validation failed. Unable to match key: kid: 'IcMvbl6kv2ZKbug2Ip9MioeTw9A'. So followed the answer mentioned IDX10501: Signature validation failed. Unable to match keys But still getting the same exception. Please let me know if something need to be configured in Azure end.Burthen
looks like the authority is not setup properly on the API. Try to navigate to your Authority discovery document: https://yourauthority.com/.well-known/openid-configuration you should see a JSON document as response. Inside the JSON document you should see a jwks_uri property, something like https://yourauthority.com/.well-known/openid-configuration/jwks. Navigate to that URL, and you'll get a json with your authority public key, look at the kid property, it should match the one on your token. Enter your token into jwt.io website to inspect its contents and compare kids (key ids). BOLMallarme
M
2

It will validate issuer, audience and lifetime by default. There's a bunch of properties in TokenValidationParameters. If you create a new instance of that class, you'll see which fields are set to true/false. Or, you could add the following to your code, breakpoint and investigate yourself.

.AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, options =>
{ ...
  options.TokenValidationParameters = new TokenValidationParameters
  {
    ValidateIssuer = false,
    ValidateAudience = false, ...
  }; ..
} ...

NB authority and issuer are pretty much the same concept. Also, mind the difference between ValidIssuer and ValidateIssuer.

Multitudinous answered 31/10, 2021 at 12:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.