How To Use JWT Authentication With Web API

In this article, we will learn how to use JWT Token Security with Web API.

Introduction

Token-based security is commonly used in today’s security architecture. There are several token-based security techniques. JWT is one of the more popular techniques. JWT token is used to identify authorized users.

What is the JWT WEB TOKEN?

  • Open Standard: Means anywhere, anytime, and anyone can use JWT.
  • Secure data transfer between any two bodies, any two users, any two servers.
  • It is digitally signed: Information is verified and trusted.
  • There is no alteration of data.
  • Compact: because JWT can be sent via URL, post request & HTTP header.
  • Fast transmission makes JWT more usable.
  • Self Contained: because JWT itself holds user information.
  • It avoids querying the database more than once after a user is logged in and has been verified.

JWT is useful for

  • Authentication
  • Secure data transfer

JWT Token Structure 

A JWT token contains a Header, a Payload, and a Signature. 

How To Use JWT Authentication With WEB API

Header

Header contains the algorithms like RSA or HMACSHA256 and the information of the type of Token.

  1. {  
  2.    “alg” : ”” Algorithm like RSA or HMACSHA256  
  3.    “Type” : ”” Type of JWT Token  
  4. }  

Payload

Payload contains the information of rows, i.e., user credentials.

  1. {  
  2.    “loginname” : ”Gajendra”  
  3.    “password”:”123#”  
  4. }  
  • It contains claims.
  • Claims are user details or additional information

Signature

{ base64urlencoded (header) +”.”+ base64urlencoded (payload) +”.”+ secret }

  • Combine base64 encoded Header , base64 encoded Payload with secret
  • These provide more security.
A combination of all headers, payload and signatures converts into JWT TOKEN. 
 

How Does JWT Work?

 
Step 1 
 
Client logs in with his/her credentials.
 
How To Use JWT Authentication With WEB API 
Step 2
 
Server generates a Jwt token at server side. 
 
How To Use JWT Authentication With WEB API
 
Step 3
 
After token generation, the server returns a token in response.
 
How To Use JWT Authentication With WEB API
Step 4
 
Now, the client sends a copy of the token to validate the token. 

How To Use JWT Authentication With WEB API 
Step 5
 
The server checks JWT token to see if it's valid or not.
 
How To Use JWT Authentication With WEB API 
Step 6
 
After the token is validated, the server sends a status message to the client.
 
How To Use JWT Authentication With WEB API 

Working With JWT

 
Step 1
 
User Login - User normally logs in with his/her credentials such as User Name and Password.
  1. [Route("UserLogin")]  
  2. [HttpPost]  
  3. public ResponseVM UserLogin(LoginVM objVM) {  
  4.     var objlst = wmsEN.Usp_Login(objVM.UserName, UtilityVM.Encryptdata(objVM.Passward), "").ToList < Usp_Login_Result > ().FirstOrDefault();  
  5.     if (objlst.Status == -1) return new ResponseVM {  
  6.         Status = "Invalid", Message = "Invalid User."  
  7.     };  
  8.     if (objlst.Status == 0) return new ResponseVM {  
  9.         Status = "Inactive", Message = "User Inactive."  
  10.     };  
  11.     else return new ResponseVM {  
  12.         Status = "Success", Message = TokenManager.GenerateToken(objVM.UserName)  
  13.     };  
  14. }  
Step 2
 
Server generates a JWT token. 

Jwt secret string

  1. private static string Secret = "ERMN05OPLoDvbTTa/QkqLNMI7cPLguaRyHzyg7n5qNBVjQmtBhz4SzYh4NBVCXi3KJHlSXKP+oi2+bXr6CUYTR==";  

Create Jwt Token

First you have to add Microsoft.IdentityModel.Tokens and System.IdentityModel.Tokens.Jwt references from NuGet Package Manager.

  1. public static string GenerateToken(string username) {  
  2.     byte[] key = Convert.FromBase64String(Secret);  
  3.     SymmetricSecurityKey securityKey = new SymmetricSecurityKey(key);  
  4.     SecurityTokenDescriptor descriptor = new SecurityTokenDescriptor {  
  5.         Subject = new ClaimsIdentity(new [] {  
  6.                 new Claim(ClaimTypes.Name, username)  
  7.             }),  
  8.             Expires = DateTime.UtcNow.AddMinutes(30),  
  9.             SigningCredentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256Signature)  
  10.     };  
  11.     JwtSecurityTokenHandler handler = new JwtSecurityTokenHandler();  
  12.     JwtSecurityToken token = handler.CreateJwtSecurityToken(descriptor);  
  13.     return handler.WriteToken(token);  
  14. }  
  15. public static ClaimsPrincipal GetPrincipal(string token) {  
  16.     try {  
  17.         JwtSecurityTokenHandler tokenHandler = new JwtSecurityTokenHandler();  
  18.         JwtSecurityToken jwtToken = (JwtSecurityToken) tokenHandler.ReadToken(token);  
  19.         if (jwtToken == nullreturn null;  
  20.         byte[] key = Convert.FromBase64String(Secret);  
  21.         TokenValidationParameters parameters = new TokenValidationParameters() {  
  22.             RequireExpirationTime = true,  
  23.                 ValidateIssuer = false,  
  24.                 ValidateAudience = false,  
  25.                 IssuerSigningKey = new SymmetricSecurityKey(key)  
  26.         };  
  27.         SecurityToken securityToken;  
  28.         ClaimsPrincipal principal = tokenHandler.ValidateToken(token, parameters, out securityToken);  
  29.         return principal;  
  30.     } catch {  
  31.         return null;  
  32.     }  
  33. }  
Step 3
   
Check for token validation.
  1. [Route("Validate")]  
  2. [HttpGet]  
  3. public ResponseVM Validate(string token, string username) {  
  4.     int UserId = new UserRepository().GetUser(username);  
  5.     if (UserId == 0) return new ResponseVM {  
  6.         Status = "Invalid", Message = "Invalid User."  
  7.     };  
  8.     string tokenUsername = TokenManager.ValidateToken(token);  
  9.     if (username.Equals(tokenUsername)) {  
  10.         return new ResponseVM {  
  11.             Status = "Success",  
  12.                 Message = "OK",  
  13.         };  
  14.     }  
  15.     return new ResponseVM {  
  16.         Status = "Invalid", Message = "Invalid Token."  
  17.     };  
  18. }  
  19. public static string ValidateToken(string token) {  
  20.     string username = null;  
  21.     ClaimsPrincipal principal = GetPrincipal(token);  
  22.     if (principal == nullreturn null;  
  23.     ClaimsIdentity identity = null;  
  24.     try {  
  25.         identity = (ClaimsIdentity) principal.Identity;  
  26.     } catch (NullReferenceException) {  
  27.         return null;  
  28.     }  
  29.     Claim usernameClaim = identity.FindFirst(ClaimTypes.Name);  
  30.     username = usernameClaim.Value;  
  31.     return username;  
  32. }  
Here is the complete TokenManager class.
  1. using Microsoft.IdentityModel.Tokens;  
  2. using System;  
  3. using System.Collections.Generic;  
  4. using System.IdentityModel.Tokens.Jwt;  
  5. using System.Linq;  
  6. using System.Security.Claims;  
  7. using System.Web;  
  8.   
  9. namespace WMS.Models.VM  
  10. {  
  11.     public class TokenManager  
  12.     {  
  13.         private static string Secret = "ERMN05OPLoDvbTTa/QkqLNMI7cPLguaRyHzyg7n5qNBVjQmtBhz4SzYh4NBVCXi3KJHlSXKP+oi2+bXr6CUYTR==";  
  14.         public static string GenerateToken(string username)  
  15.         {  
  16.             byte[] key = Convert.FromBase64String(Secret);  
  17.             SymmetricSecurityKey securityKey = new SymmetricSecurityKey(key);  
  18.             SecurityTokenDescriptor descriptor = new SecurityTokenDescriptor  
  19.             {  
  20.                 Subject = new ClaimsIdentity(new[] {  
  21.                       new Claim(ClaimTypes.Name, username)}),  
  22.                 Expires = DateTime.UtcNow.AddMinutes(30),  
  23.                 SigningCredentials = new SigningCredentials(securityKey,  
  24.                 SecurityAlgorithms.HmacSha256Signature)  
  25.             };  
  26.   
  27.             JwtSecurityTokenHandler handler = new JwtSecurityTokenHandler();  
  28.             JwtSecurityToken token = handler.CreateJwtSecurityToken(descriptor);  
  29.             return handler.WriteToken(token);  
  30.         }  
  31.         public static ClaimsPrincipal GetPrincipal(string token)  
  32.         {  
  33.             try  
  34.             {  
  35.                 JwtSecurityTokenHandler tokenHandler = new JwtSecurityTokenHandler();  
  36.                 JwtSecurityToken jwtToken = (JwtSecurityToken)tokenHandler.ReadToken(token);  
  37.                 if (jwtToken == null)  
  38.                     return null;  
  39.                 byte[] key = Convert.FromBase64String(Secret);  
  40.                 TokenValidationParameters parameters = new TokenValidationParameters()  
  41.                 {  
  42.                     RequireExpirationTime = true,  
  43.                     ValidateIssuer = false,  
  44.                     ValidateAudience = false,  
  45.                     IssuerSigningKey = new SymmetricSecurityKey(key)  
  46.                 };  
  47.                 SecurityToken securityToken;  
  48.                 ClaimsPrincipal principal = tokenHandler.ValidateToken(token,  
  49.                       parameters, out securityToken);  
  50.                 return principal;  
  51.             }  
  52.             catch  
  53.             {  
  54.                 return null;  
  55.             }  
  56.         }  
  57.         public static string ValidateToken(string token)  
  58.         {  
  59.             string username = null;  
  60.             ClaimsPrincipal principal = GetPrincipal(token);  
  61.             if (principal == null)  
  62.                 return null;  
  63.             ClaimsIdentity identity = null;  
  64.             try  
  65.             {  
  66.                 identity = (ClaimsIdentity)principal.Identity;  
  67.             }  
  68.             catch (NullReferenceException)  
  69.             {  
  70.                 return null;  
  71.             }  
  72.             Claim usernameClaim = identity.FindFirst(ClaimTypes.Name);  
  73.             username = usernameClaim.Value;  
  74.             return username;  
  75.         }  
  76.           
  77.     }  
  78. }  

Summary

In this article, I have explained the Jwt token authentication and how it works.