In this section, we are going to discuss very basic and important thing Authentication and that is via JWT aka JSON Web Token. Basically, after first successful login, we will be creating JSON token with some expiry time and this token will be sent as part of Header with every consecutive request afterwards. This makes sure that users won’t need to supply username and password for every secured resource access.
Code Link:- https://github.com/rahulsahay19/JWT.Server
Background:- JWT is JSON based access token which is basically created for claims. This is usually encrypted with security algorithm say Hash Algorithms. There are generally three parts of JWTs as shown in the image above.
1st part is header, which keeps the algorithm info like HS256/HS512 or any other. You can see detail supported algorithm list here. In our demo, we will be using HS256.
2nd part is payload section, where our custom claims like username, email id etc plus standard claims such as
iss:- The “iss” (issuer) claim identifies the principal that issued the JWT. The processing of this claim is generally application specific. The “iss” value is a case-sensitive string containing a StringOrURI value. Use of this claim is OPTIONAL.
iat:- The “iat” (issued at) claim identifies the time at which the JWT was issued. This claim can be used to determine the age of the JWT. Its value MUST be a number containing a NumericDate value. Use of this claim is OPTIONAL., nbf, sub etc.
sub:- The “sub” (subject) claim identifies the principal that is the subject of the JWT. The claims in a JWT are normally statements about the subject. The subject value MUST either be scoped to be locally unique in the context of the issuer or be globally unique. The processing of this claim is generally application specific. The “sub” value is a case-sensitive string containing a StringOrURI value. Use of this claim is OPTIONAL.
exp:- The “exp” (expiration time) claim identifies the expiration time on or after which the JWT MUST NOT be accepted for processing. The processing of the “exp” claim requires that the current date/time MUST be before the expiration date/time listed in the “exp” claim. Detailed info can be found here.
3rd part is signature. In order to create the signature, we need to take the encoded header, payload, signature and then sign it. The signature is used to verify the message wasn’t changed along the way, and, in the case of tokens signed with a private key, it can also verify that the sender of the JWT is who it says it is.
Having said that, let’s get started with demo. You can download the source code from here.
Let me explain the code here. Here, I have a simple User Credential object which looks like
You can extend this further if you want. One point to note here, that in order to explain the concepts, I kept it pretty simple. And, I have IAuthManager interface with pretty simple authenticate method. We can again have different methods here like logout, revoke access, etc. Feel free to clone the solution and extend it. Its implementation also very simple as shown below in the snippet.
Now, let’s understand what’s done here. We have first created a token handler, then we read the token key from config file and converted the same into bytes. Then, we created security token descriptor with name as claim. I have also passed expiration time and signed the token using HmacSha256Signature and providing the secret key to it. Now, my Authentication controller looks like
As you can see, this controller is quite straight forward with anonymous method, wherein you will be providing username and password first and then token will be created with this. Then, we will use this token to call our other method.
Next comes startup configuration for my pipeline configuration and DI registration. Before that, we need to install the following packages to achieve the required result.
Having installed above packages, now let’s go ahead and setup our pipeline.
First, I added authentication where in I provided, default authentication scheme and default challenge scheme. Next, I added JwtBearer to it. Also, I have provided token validation parameter to validate the issuer signing key. Here, I kept other options as false for now. In coming post, we will delve in detail where in we will be checking how to validate audience and issuer at the same time with other options and claims. Here, IAuthManager expects token to be passed. Hence, passed with new AuthManager section.
With this, we have configured our handler to decrypt the token and ensure that user is authenticated. Having said that, let’s go ahead and run the app. Here, when I go ahead and try to access the url like this in browser https://localhost:5001/api/authentication, it will give 401 error. Now, let’s go ahead try generating the token from postman like shown below
Upon sending the request, this will generate the token like shown below.
Now, if you decrypt this token with jwt.io, you will find below info.
Now, I can use this token and attach with header to call the other method which is protected like shown below. Here, I have attached Authorization with Bearer token. Make sure to provide space between Bearer and token.
With this, once, I click on send button, I will get 200 Ok response with the result like shown below.
You can also test this in browser. For that, you need to install one chrome extension ModHeader and provide the value like this
After this, send the request in the browser, it will fetch result like shown below.
I hope, you would have liked today’s discussion. In coming post, we will delve further. Till then stay tuned and happy coding.