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.
Header
Header contains the algorithms like RSA or HMACSHA256 and the information of the type of Token.
- {
- “alg” : ”” Algorithm like RSA or HMACSHA256
- “Type” : ”” Type of JWT Token
- }
Payload
Payload contains the information of rows, i.e., user credentials.
- {
- “loginname” : ”Gajendra”
- “password”:”123#”
- }
- 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.
Step 2
Server generates a Jwt token at server side.
Step 3
After token generation, the server returns a token in response.
Step 4
Now, the client sends a copy of the token to validate the token.
Step 5
The server checks JWT token to see if it's valid or not.
Step 6
After the token is validated, the server sends a status message to the client.
Working With JWT
Step 1
User Login - User normally logs in with his/her credentials such as User Name and Password.
- [Route("UserLogin")]
- [HttpPost]
- public ResponseVM UserLogin(LoginVM objVM) {
- var objlst = wmsEN.Usp_Login(objVM.UserName, UtilityVM.Encryptdata(objVM.Passward), "").ToList < Usp_Login_Result > ().FirstOrDefault();
- if (objlst.Status == -1) return new ResponseVM {
- Status = "Invalid", Message = "Invalid User."
- };
- if (objlst.Status == 0) return new ResponseVM {
- Status = "Inactive", Message = "User Inactive."
- };
- else return new ResponseVM {
- Status = "Success", Message = TokenManager.GenerateToken(objVM.UserName)
- };
- }
Step 2
Server generates a JWT token.
- 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.
- public static string GenerateToken(string username) {
- byte[] key = Convert.FromBase64String(Secret);
- SymmetricSecurityKey securityKey = new SymmetricSecurityKey(key);
- SecurityTokenDescriptor descriptor = new SecurityTokenDescriptor {
- Subject = new ClaimsIdentity(new [] {
- new Claim(ClaimTypes.Name, username)
- }),
- Expires = DateTime.UtcNow.AddMinutes(30),
- SigningCredentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256Signature)
- };
- JwtSecurityTokenHandler handler = new JwtSecurityTokenHandler();
- JwtSecurityToken token = handler.CreateJwtSecurityToken(descriptor);
- return handler.WriteToken(token);
- }
- public static ClaimsPrincipal GetPrincipal(string token) {
- try {
- JwtSecurityTokenHandler tokenHandler = new JwtSecurityTokenHandler();
- JwtSecurityToken jwtToken = (JwtSecurityToken) tokenHandler.ReadToken(token);
- if (jwtToken == null) return null;
- byte[] key = Convert.FromBase64String(Secret);
- TokenValidationParameters parameters = new TokenValidationParameters() {
- RequireExpirationTime = true,
- ValidateIssuer = false,
- ValidateAudience = false,
- IssuerSigningKey = new SymmetricSecurityKey(key)
- };
- SecurityToken securityToken;
- ClaimsPrincipal principal = tokenHandler.ValidateToken(token, parameters, out securityToken);
- return principal;
- } catch {
- return null;
- }
- }
Step 3
Check for token validation.
- [Route("Validate")]
- [HttpGet]
- public ResponseVM Validate(string token, string username) {
- int UserId = new UserRepository().GetUser(username);
- if (UserId == 0) return new ResponseVM {
- Status = "Invalid", Message = "Invalid User."
- };
- string tokenUsername = TokenManager.ValidateToken(token);
- if (username.Equals(tokenUsername)) {
- return new ResponseVM {
- Status = "Success",
- Message = "OK",
- };
- }
- return new ResponseVM {
- Status = "Invalid", Message = "Invalid Token."
- };
- }
- public static string ValidateToken(string token) {
- string username = null;
- ClaimsPrincipal principal = GetPrincipal(token);
- if (principal == null) return null;
- ClaimsIdentity identity = null;
- try {
- identity = (ClaimsIdentity) principal.Identity;
- } catch (NullReferenceException) {
- return null;
- }
- Claim usernameClaim = identity.FindFirst(ClaimTypes.Name);
- username = usernameClaim.Value;
- return username;
- }
Here is the complete TokenManager class.
- using Microsoft.IdentityModel.Tokens;
- using System;
- using System.Collections.Generic;
- using System.IdentityModel.Tokens.Jwt;
- using System.Linq;
- using System.Security.Claims;
- using System.Web;
-
- namespace WMS.Models.VM
- {
- public class TokenManager
- {
- private static string Secret = "ERMN05OPLoDvbTTa/QkqLNMI7cPLguaRyHzyg7n5qNBVjQmtBhz4SzYh4NBVCXi3KJHlSXKP+oi2+bXr6CUYTR==";
- public static string GenerateToken(string username)
- {
- byte[] key = Convert.FromBase64String(Secret);
- SymmetricSecurityKey securityKey = new SymmetricSecurityKey(key);
- SecurityTokenDescriptor descriptor = new SecurityTokenDescriptor
- {
- Subject = new ClaimsIdentity(new[] {
- new Claim(ClaimTypes.Name, username)}),
- Expires = DateTime.UtcNow.AddMinutes(30),
- SigningCredentials = new SigningCredentials(securityKey,
- SecurityAlgorithms.HmacSha256Signature)
- };
-
- JwtSecurityTokenHandler handler = new JwtSecurityTokenHandler();
- JwtSecurityToken token = handler.CreateJwtSecurityToken(descriptor);
- return handler.WriteToken(token);
- }
- public static ClaimsPrincipal GetPrincipal(string token)
- {
- try
- {
- JwtSecurityTokenHandler tokenHandler = new JwtSecurityTokenHandler();
- JwtSecurityToken jwtToken = (JwtSecurityToken)tokenHandler.ReadToken(token);
- if (jwtToken == null)
- return null;
- byte[] key = Convert.FromBase64String(Secret);
- TokenValidationParameters parameters = new TokenValidationParameters()
- {
- RequireExpirationTime = true,
- ValidateIssuer = false,
- ValidateAudience = false,
- IssuerSigningKey = new SymmetricSecurityKey(key)
- };
- SecurityToken securityToken;
- ClaimsPrincipal principal = tokenHandler.ValidateToken(token,
- parameters, out securityToken);
- return principal;
- }
- catch
- {
- return null;
- }
- }
- public static string ValidateToken(string token)
- {
- string username = null;
- ClaimsPrincipal principal = GetPrincipal(token);
- if (principal == null)
- return null;
- ClaimsIdentity identity = null;
- try
- {
- identity = (ClaimsIdentity)principal.Identity;
- }
- catch (NullReferenceException)
- {
- return null;
- }
- Claim usernameClaim = identity.FindFirst(ClaimTypes.Name);
- username = usernameClaim.Value;
- return username;
- }
-
- }
- }
Summary
In this article, I have explained the Jwt token authentication and how it works.