Arash
Arash

Reputation: 3688

How Jwt token issued by IdentiyServer is validate in Web Api Application

I am using IdentiyServer to issue a JWT Token to a client, token contains role claims and some other claims, this part works fine, I get the the access token with desired claims.

And in my web API application I have added the following code to support JWT authentication:

 services.AddAuthentication(options =>
            {
                options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
            })
            .AddJwtBearer(options =>
            {
                options.RequireHttpsMetadata = false;
                options.Authority = "http://localhost:5004";
                IdentityModelEventSource.ShowPII = true;
                options.TokenValidationParameters = new TokenValidationParameters()
                {
                    ValidateAudience = false,
                    ValidateIssuer = false,
                    ValidateLifetime = false,
                    ValidateIssuerSigningKey = true,
                    IssuerSigningKey = "what is this ?"
                };

The question is, suppose a hacker generates a JWT token with whatever header and body and claims he wants and signs it, how does my web api application validate the signature? How can I share IssuerSigningKey with identityServer and my web api application?

Is IssuerSigningKey the same as ClientSecrets in identityServer?

I have gone through IdentityServer documentation, but couldn't find an answer.

Upvotes: 2

Views: 1937

Answers (3)

Mrinal Kamboj
Mrinal Kamboj

Reputation: 11478

In the question as it seems, that complete OAuth flow using an OAuth or Open Id server is not very clear, let's consider various questions and options.

I am using IdentiyServer to issue a JWT Token to a client, token contains role claims and some other claims, this part works fine, I get the the access token with desired claims.

Let's segregate the Authentication server from Authorization, generally when we integrate any of the social logins, what they do is provide an access token and we use callback to generate a JWT Authroization token at our server, which we control like Backend server

What's the difference between two ?

Authentication server generally know very few details about us, mostly they just verify email and return success, they have no ability to assign roles and other details, which vary from application to application

What shall we do then ?

Receive Access Token, fetch details like email from it, fetch all details related to that email, create a json payload, use an algorithm with either Symmetric (only one key) or Asymmetric encryption (generate private public key pair), check this video to know details about JWT with much more clarity. In Symmetric encryption we use same key to encode / decode, while in Asymmetric encryption we encode using private key and decode using public key. As you would check In JWT encoding and decoding simply means hashing header.payload and comparing the two to ensure no tampering

Remaining questions regarding type of encryption and hacker:

  1. Asymmetric encryption is stronger and safer, but it has a performance penalty
  2. If Client Ui (Javascript) doesn't needs to decode JWT then Symmetric encryption is good enough
  3. In Asymmetric encryption every client has a public key while Main token signed using private key and if token is changed / tampered, then decoding the key would fail, thus error. Matching key is just comparing the hash of header.jsonpayload
  4. In symmetric encryption there's onky 1 key, which remains at server, for decoding the jwt token passed by the client.
  5. Hacker who sniffs out the JWT token over network, has no option but to use the same, else token decoding will fail, so the best bet is impersonation, but that is also good till time expiry, that's why there's a refresh token, which seamlessly refresh the access token and plugged application will generate new jwt token. Also nowdays there are check against impersonation why popping up a messages, when there's an attempt to sign in from unknown machine
  6. Why in every call, we don't go to the identity server, since that make token verification slow process, that also the reason to generate JWT
  7. Every call to web api shall use a plugged in middleware to decode / verify token and proceed further, relogin / authentication shall only happen when JWT token expires

ASP.Net Web API Specific Changes

I code in Python using Fast API, what we do is use a middleware, which is similar to interceptor / filter in Asp.Net, which will intercept all the calls to the controller / api, fetch the token, decode, verify and allow the call to continue or throw an error to relogin, please note encoding happens in the callback from the authentication server. A sample code in Python, https://pyjwt.readthedocs.io/en/latest/usage.html

For C# this link is a good option, https://www.c-sharpcorner.com/article/asp-net-web-api-2-creating-and-validating-jwt-json-web-token/

Here as you can see the code, where explicit Filter is added to verify the token. It use a decorator, [Authorize] to invoke the authorization filter

public static void Register(HttpConfiguration config) {  
 // Web API configuration and services    
 config.SuppressDefaultHostAuthentication();  
 config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));  
  
 // Web API routes    
 config.MapHttpAttributeRoutes();  
  
 config.Routes.MapHttpRoute(  
  name: "DefaultApi",  
  routeTemplate: "api/{controller}/{action}/{id}",  
  defaults: new {  
   id = RouteParameter.Optional  
  }  
 );  
}  

Upvotes: 1

Tore Nestenius
Tore Nestenius

Reputation: 19941

When you use AddJwtBearer, it will download the public signing key from your IdentityServer (http://localhost:5004) and use this public key to verify that the signature in the received JWT token was issued by the expected issuer. AddJwtBearer will refresh the downloaded public key every 24 hours by default.

IssuerSigningKey you do not need to set in the API. In general you should disable as few checks as possible in he TokenValidationParameters object.

In production you should try to set ShowPII to false, because otherwise things like tokens and other secrets might end up in the logs.

Is IssuerSigningKey the same as ClientSecrets in identityServer?

No, they are two separate things. ClientSecret is like a password for the client, when it authenticates against IdentityServer.

SigningKey you set in IdentityServer and it represents the public/private siging key. The key can either be an RSA or ECDSA key.

Upvotes: 3

Tim Biegeleisen
Tim Biegeleisen

Reputation: 521914

While a hacker can certainly generate a bogus JWT with some header and claims, he cannot sign the token using the server's private key, unless he also hacks your server to steal the key. So, in practice, a JWT usually bears a checksum at the end of the token, which is a hash based on the token's content and the server key. If your server receives an incoming JWT and the checksum does not validate, then it should reject that JWT.

Upvotes: 1

Related Questions