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?

JWT is useful for

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 == null) return 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 == null) return 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. namespace WMS.Models.VM
  9. {
  10. public class TokenManager
  11. {
  12. private static string Secret = "ERMN05OPLoDvbTTa/QkqLNMI7cPLguaRyHzyg7n5qNBVjQmtBhz4SzYh4NBVCXi3KJHlSXKP+oi2+bXr6CUYTR==";
  13. public static string GenerateToken(string username)
  14. {
  15. byte[] key = Convert.FromBase64String(Secret);
  16. SymmetricSecurityKey securityKey = new SymmetricSecurityKey(key);
  17. SecurityTokenDescriptor descriptor = new SecurityTokenDescriptor
  18. {
  19. Subject = new ClaimsIdentity(new[] {
  20. new Claim(ClaimTypes.Name, username)}),
  21. Expires = DateTime.UtcNow.AddMinutes(30),
  22. SigningCredentials = new SigningCredentials(securityKey,
  23. SecurityAlgorithms.HmacSha256Signature)
  24. };
  25. JwtSecurityTokenHandler handler = new JwtSecurityTokenHandler();
  26. JwtSecurityToken token = handler.CreateJwtSecurityToken(descriptor);
  27. return handler.WriteToken(token);
  28. }
  29. public static ClaimsPrincipal GetPrincipal(string token)
  30. {
  31. try
  32. {
  33. JwtSecurityTokenHandler tokenHandler = new JwtSecurityTokenHandler();
  34. JwtSecurityToken jwtToken = (JwtSecurityToken)tokenHandler.ReadToken(token);
  35. if (jwtToken == null)
  36. return null;
  37. byte[] key = Convert.FromBase64String(Secret);
  38. TokenValidationParameters parameters = new TokenValidationParameters()
  39. {
  40. RequireExpirationTime = true,
  41. ValidateIssuer = false,
  42. ValidateAudience = false,
  43. IssuerSigningKey = new SymmetricSecurityKey(key)
  44. };
  45. SecurityToken securityToken;
  46. ClaimsPrincipal principal = tokenHandler.ValidateToken(token,
  47. parameters, out securityToken);
  48. return principal;
  49. }
  50. catch
  51. {
  52. return null;
  53. }
  54. }
  55. public static string ValidateToken(string token)
  56. {
  57. string username = null;
  58. ClaimsPrincipal principal = GetPrincipal(token);
  59. if (principal == null)
  60. return null;
  61. ClaimsIdentity identity = null;
  62. try
  63. {
  64. identity = (ClaimsIdentity)principal.Identity;
  65. }
  66. catch (NullReferenceException)
  67. {
  68. return null;
  69. }
  70. Claim usernameClaim = identity.FindFirst(ClaimTypes.Name);
  71. username = usernameClaim.Value;
  72. return username;
  73. }
  74. }
  75. }

Summary

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