Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does AddJwtBearer() Do what I think it does?

I am trying to determine if the JwtBearer Service provided for .net core 3.0, does it actually use the asymettric signing key that is provided by my oidc providers well known configuration???

I can't find any documentation around this.

.AddJwtBearer(opt =>
                    {
                        opt.Authority = "http://localhost:8180/auth/realms/master";
                        opt.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters
                        {
                            ValidateIssuer = true,
                            ValidateAudience = false,
                            ValidateLifetime = true,
                            ValidateIssuerSigningKey = true
                        };

I am using Keycloak 4.8.3 as my oidc provider. The closest documentation I could find was here. https://developer.okta.com/blog/2018/03/23/token-authentication-aspnetcore-complete-guide

The relevant piece is here:

If you let the JwtBearer middleware auto-configure via the discovery document, this all works automatically!

Did that above code do all that? Is this still relevant in 3.0 since we don't register the middleware anymore??

I bet a lot of people don't know about Asymetric Signing keys, and why they are so important. We have abstracted away so much from the developer, that now I don't even know if my api is secure.

So the final question is. Does the .AddJwtBearer service with "ValidateIssuerSigningKey" periodically check the wellknown or whatever discovery document to grab the latest asymettric signing key?

like image 950
christopher clark Avatar asked Nov 07 '19 23:11

christopher clark


People also ask

What is ValidateIssuer in JWT?

ValidateIssuer, validates that the iss claim inside the access token matches the issuer(authority) that the API trusts (Ie, your token service). Verifies that the issuer of the token is what this API expects.

What is authentication scheme .NET core?

Authentication is the process of determining a user's identity. Authorization is the process of determining whether a user has access to a resource. In ASP.NET Core, authentication is handled by the authentication service, IAuthenticationService, which is used by authentication middleware.

What is JWT authority?

Authority is the address of the token-issuing authentication server. The JWT bearer authentication middleware will use this URI to find and retrieve the public key that can be used to validate the token's signature. It will also confirm that the iss parameter in the token matches this URI.


Video Answer


2 Answers

I was wondering same - research/debugging showed that JwtBearer indeed trying to contact authority to get public key.

Here is function called during validation :

// System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.cs

protected virtual SecurityKey ResolveIssuerSigningKey(string token, JwtSecurityToken jwtToken, TokenValidationParameters validationParameters)
            {
                if (validationParameters == null)
                    throw LogHelper.LogArgumentNullException(nameof(validationParameters));

                if (jwtToken == null)
                    throw LogHelper.LogArgumentNullException(nameof(jwtToken));

                return JwtTokenUtilities.FindKeyMatch(jwtToken.Header.Kid, jwtToken.Header.X5t, validationParameters.IssuerSigningKey, validationParameters.IssuerSigningKeys);
            }

Obviously this logic to contact authority for public key is called only when you set Oauth authority in your configuration:

 .AddJwtBearer(o =>{
     o.Authority = "https://authorityUri/";
 })

AddJwtBearer middleware handler internally will add ".well-known/openid-configuration" string to o.Authority and will try to fetch JSON with details of authority server. (Google example: https://accounts.google.com/.well-known/openid-configuration).

Next step - get jwks_uri, (in case of google https://www.googleapis.com/oauth2/v3/certs) and fetch jwks file, which will have data used for signature validation (publicKey, algorithm, initial vector)..

After all this steps, JwtBearer validates token signature.

Just for info - JwtBearer can validate token without authority if you configure it with your own Signing Key issuer, like this:

.AddJwtBearer(o =>{
         o.TokenValidationParameters.IssuerSigningKey = GetKey();
         //in this case you need to provide valid audience or disable validation
         o.TokenValidationParameters.ValidateAudience = false
         //in this case you need to provide valid issuer or disable validation
         o.TokenValidationParameters.ValidateIssuer= false
     })

Microsoft.IdentityModel.Tokens.SecurityKey = GetKey(){
            var key = "Secret_Pass";
            return new SymmetricSecurityKey(Encoding.UTF8.GetBytes(key));
}

In this case you need either provide issuer and audience or disable validation. This configuration can be used for B2B cases - server to server communications - when you don't have Oauth server and issue tokens yourself using shared secret.

For the full picture look at this configuration - both authority and issuer key set:

 .AddJwtBearer(o =>{
     o.Authority = "https://authorityUri/";
     o.TokenValidationParameters.IssuerSigningKey = GetKey();
 })

In this case authority will not be touched and your locally generated key will be used to validate token, so priority is TokenValidationParameters.IssuerSigningKey. Means no reason to add Authority.

like image 86
Vitaliy Markitanov Avatar answered Sep 30 '22 11:09

Vitaliy Markitanov


You don't need to set TokenValidationParameters . If Authority which is the address of the token-issuing authentication server is set correctly , the JWT bearer middleware will use this URI to find and retrieve the public key that can be used to validate the token’s signature. It will also confirm that the iss parameter in the token matches this URI . Middleware will help get keys from the OIDC metadata and cache the keys .

TokenValidationParameters can be used in scenario that you want to validate tokens without access to the issuing server. Instead, you wanted to use a public key that was already present locally to validate incoming tokens.Then you can not set the Authority, setting ValidateIssuerSigningKeyand ValidateIssuer , and finally set IssuerSigningKey which is the public key used for validating incoming JWT tokens.

like image 35
Nan Yu Avatar answered Sep 30 '22 10:09

Nan Yu