Introduction

When we want to restrict unauthorized users from accessing data from our application, then we need to apply token-based authentication in our application so that only valid users can access the data. Usually, ASP.NET WebAPI 2 provides Identity based authentication that is implemented in code first approach. But there may be some scenario when we have to go with database first approach and in this aspect, the identity token may have some hassle in implementation. This custom database first approach token authentication will enable you to apply token-based authentication in your application in a simple way with no hassle.


Steps of implementation

You need to go through the following steps to implement custom token-based authentication.

Step 1

Create a database with name Tokenization and add 3 tables there as following.

  1. CREATE DATABASE Tokenization
  2. USE [Tokenization]
  3. GO
  4. CREATE TABLE Employees
  5. (
  6. EmployeeId INT PRIMARY KEY IDENTITY(1,1) NOT NULL,
  7. EmployeeName VARCHAR(255) NULL,
  8. EmployeeEmail VARCHAR(255) NULL,
  9. EmployeeMobileNumber VARCHAR(12) NULL,
  10. EmployeeAddress VARCHAR(255) NULL
  11. )
  12. GO
  13. CREATE TABLE Users
  14. (
  15. UserId INT PRIMARY KEY IDENTITY(1,1) NOT NULL,
  16. FullName VARCHAR(255) NULL,
  17. LoginName VARCHAR(255) NOT NULL,
  18. PasswordNo VARCHAR(255) NOT NULL,
  19. EmployeeId INT NOT NULL
  20. )
  21. GO
  22. CREATE TABLE TokenManager
  23. (
  24. TokenID BIGINT PRIMARY KEY IDENTITY(1,1) NOT NULL,
  25. TokenKey VARCHAR(255) NULL,
  26. IssuedOn DATETIME NULL,
  27. ExpiresOn DATETIME NULL,
  28. CreatedOn DATETIME NULL,
  29. UserId INT NULL
  30. )
  31. GO

Step 2

Create a Web API 2 Project and name it as CustomTokenizationDatabaseFirst.

ASP.NET

Step 3

Create a folder by right clicking on CustomTokenizationDatabaseFirst Project and name it as TokenFilter. Under this folder create the following class as ApiAuthorizeAttribute.

ASP.NET

Code Snippet for ApiAuthorizeAttribute Class

  1. public class ApiAuthorizeAttribute : AuthorizeAttribute
  2. {
  3. private readonly Entities _entities = new Entities();
  4. private readonly IUserRepository _userRepository = new UserRepository();
  5. public override void OnAuthorization(HttpActionContext filterContext)
  6. {
  7. if (Authorize(filterContext))
  8. {
  9. return;
  10. }
  11. HandleUnauthorizedRequest(filterContext);
  12. }
  13. protected override void HandleUnauthorizedRequest(HttpActionContext filterContext)
  14. {
  15. base.HandleUnauthorizedRequest(filterContext);
  16. }
  17. //Here Getting the token from request header and decrypting real information which hidden in token key
  18. private bool Authorize(HttpActionContext actionContext)
  19. {
  20. try
  21. {
  22. var encodedString = actionContext.Request.Headers.GetValues("Token").FirstOrDefault();
  23. bool validFlag = false;
  24. if (!string.IsNullOrEmpty(encodedString))
  25. {
  26. var key = PasswordHash.DecryptText(encodedString);
  27. string[] parts = key.Split('|');
  28. Type myType = typeof(WebApiConfig);
  29. var myNamespace = myType.Namespace;
  30. string protocol = HttpContext.Current.Request.IsSecureConnection ? "https://" : "http://";
  31. string myApiUrl = protocol + HttpContext.Current.Request.Url.Authority;
  32. var userId = Convert.ToInt32(parts[0]); // UserID
  33. var randomKey = parts[1]; // Random Key
  34. var nameSpace = parts[2]; // NameSpace
  35. var apiUrl = parts[3]; // apiUrl
  36. long ticks = long.Parse(parts[4]); // Ticks
  37. var issuedOn = new DateTime(ticks);
  38. var userInfo = _userRepository.GetUserById(userId);
  39. if (userInfo != null && myNamespace==nameSpace && myApiUrl==apiUrl)
  40. {
  41. // Validating Time
  42. var expiresOn = (from token in _entities.TokenManagers
  43. where token.UserId == userId && token.TokenKey == encodedString
  44. select token.ExpiresOn).FirstOrDefault();
  45. validFlag = (DateTime.Now <= expiresOn);
  46. }
  47. }
  48. return validFlag;
  49. }
  50. catch (Exception ex)
  51. {
  52. return false;
  53. }
  54. }
  55. }

Step 4

How long will your token be vaild? You have to define it in Web.Config file under the <appSettings></appSettings> XML tag. I have set up 45 minutes as token expiry time. You may customize it as per your requirements.

See the follwing code,

Code Snippet for Token Expiarity

  1. <appSettings>
  2. <add key="TokenExpiry" value="45" />
  3. </appSettings>

Step 5

There will be a Model folder in your newly created project add the following JSON formatter class which will serialize JSON data.This Class will be used in web API controller Class.

Code Snippet for Json formatter

  1. public static class RequestFormat
  2. {
  3. public static JsonMediaTypeFormatter JsonFormaterString()
  4. {
  5. var formatter = new JsonMediaTypeFormatter();
  6. var json = formatter.SerializerSettings;
  7. json.DateFormatHandling = Newtonsoft.Json.DateFormatHandling.MicrosoftDateFormat;
  8. json.DateTimeZoneHandling = Newtonsoft.Json.DateTimeZoneHandling.Utc;
  9. json.NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore;
  10. json.ContractResolver = new CamelCasePropertyNamesContractResolver();
  11. return formatter;
  12. }
  13. }

Add another class under Model Folder which will be used for every API response model.

Code Snippet for API Response Model

  1. // This Class will be used for every API Response It's a response format actually
  2. public class Confirmation
  3. {
  4. public string ResponseStatus { get; set; }
  5. public string Message { get; set; }
  6. public object ResponseData { get; set; }
  7. }

Add three (3) sub folders under Model folder with the following naming convention,

ASP.NET

IRepository

Add the following code in IRepository sub folder with separate IInterface file,

  1. public interface IEmployeeRepository
  2. {
  3. object GetAllEmployees();
  4. }
  5. public interface IUserRepository
  6. {
  7. User GetUserById(int userId);
  8. User GetUserByLoginName(string userName);
  9. }
  10. internal interface ILoginRepository
  11. {
  12. object LoginInformation(string userName, string password);
  13. bool IsTokenAlreadyExists(long userId);
  14. int DeleteGenerateToken(long userId);
  15. int InsertToken(TokenManager token);
  16. string GenerateToken(long userId, System.DateTime issuedOn);
  17. }

Repository

Add the following code in Repository sub folder. Each implementation should have a separate class file,

  1. //Implementation of IEmployeeRepository
  2. public class EmployeeRepository : IEmployeeRepository
  3. {
  4. private readonly Entities _entities;
  5. public EmployeeRepository()
  6. {
  7. this._entities = new Entities();
  8. }
  9. public object GetAllEmployees()
  10. {
  11. try
  12. {
  13. var employee = (from emp in _entities.Employees
  14. select new
  15. {
  16. EmployeeId = emp.EmployeeId,
  17. EmployeeName = emp.EmployeeName,
  18. EmployeeEmail = emp.EmployeeEmail,
  19. EmployeeMobileNumber = emp.EmployeeMobileNumber,
  20. EmployeeAddress = emp.EmployeeAddress
  21. }).OrderByDescending(e => e.EmployeeId).ToList();
  22. return employee;
  23. }
  24. catch (Exception)
  25. {
  26. throw;
  27. }
  28. }
  29. }
  30. //Implementation of IUserRepository
  31. public class UserRepository : IUserRepository
  32. {
  33. private readonly Entities _entities;
  34. public UserRepository()
  35. {
  36. this._entities = new Entities();
  37. }
  38. public User GetUserById(int userId)
  39. {
  40. var user = _entities.Users.Find(userId);
  41. return user;
  42. }
  43. public User GetUserByLoginName(string userName)
  44. {
  45. try
  46. {
  47. var userInfo = _entities.Users.FirstOrDefault(x => x.LoginName == userName);
  48. return userInfo;
  49. }
  50. catch (Exception ex)
  51. {
  52. return null;
  53. }
  54. }
  55. }
  56. //Implementation of ILoginRepository
  57. public class LoginRepository : ILoginRepository
  58. {
  59. private readonly Entities _entities;
  60. private readonly IUserRepository _userRepository;
  61. public LoginRepository()
  62. {
  63. this._entities = new Entities();
  64. this._userRepository = new UserRepository();
  65. }
  66. public object LoginInformation(string userName, string password)
  67. {
  68. try
  69. {
  70. var checkIsUserExists =
  71. _entities.Users.FirstOrDefault(x => x.LoginName == userName && x.PasswordNo == password);
  72. if (checkIsUserExists != null)
  73. {
  74. LoginModel login = new LoginModel();
  75. login.UserId = checkIsUserExists.UserId;
  76. login.LoginName = checkIsUserExists.LoginName;
  77. login.PasswordNo = checkIsUserExists.PasswordNo;
  78. login.FullName = checkIsUserExists.FullName;
  79. return login;
  80. }
  81. else
  82. {
  83. return null;
  84. }
  85. }
  86. catch (Exception)
  87. {
  88. return null;
  89. }
  90. }
  91. public bool IsTokenAlreadyExists(long userId)
  92. {
  93. try
  94. {
  95. var result = (from token in _entities.TokenManagers
  96. where token.UserId == userId
  97. select token).Count();
  98. if (result > 0)
  99. {
  100. return true;
  101. }
  102. else
  103. {
  104. return false;
  105. }
  106. }
  107. catch (Exception ex)
  108. {
  109. return false;
  110. }
  111. }
  112. public int DeleteGenerateToken(long userId)
  113. {
  114. try
  115. {
  116. var token = _entities.TokenManagers.SingleOrDefault(x => x.UserId == userId);
  117. if (token != null) _entities.TokenManagers.Remove(token);
  118. return _entities.SaveChanges();
  119. }
  120. catch (Exception ex)
  121. {
  122. throw;
  123. }
  124. }
  125. public int InsertToken(TokenManager token)
  126. {
  127. try
  128. {
  129. _entities.TokenManagers.Add(token);
  130. return _entities.SaveChanges();
  131. }
  132. catch (Exception ex)
  133. {
  134. throw;
  135. }
  136. }
  137. public string GenerateToken(long userId, DateTime issuedOn)
  138. {
  139. try
  140. {
  141. Type myType = typeof(WebApiConfig);
  142. var myNamespace = myType.Namespace;
  143. string protocol = HttpContext.Current.Request.IsSecureConnection ? "https://" : "http://";
  144. string apiUrl = protocol + HttpContext.Current.Request.Url.Authority;
  145. string randomnumber =
  146. string.Join("|", new string[]{
  147. Convert.ToString(userId),
  148. KeyGenerator.GetUniqueKey(),
  149. myNamespace,
  150. apiUrl,
  151. Convert.ToString(issuedOn.Ticks)
  152. });
  153. return PasswordHash.EncryptText(randomnumber);
  154. }
  155. catch (Exception ex)
  156. {
  157. throw;
  158. }
  159. }
  160. }
  161. // Class Token Algorithm
  162. public static class KeyGenerator
  163. {
  164. //Here the algorith of how token will be generated
  165. public static string GetUniqueKey(int maxSize = 15)
  166. {
  167. var chars = new char[62];
  168. chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890".ToCharArray();
  169. var data = new byte[1];
  170. using (var crypto = new RNGCryptoServiceProvider())
  171. {
  172. data = new byte[maxSize];
  173. crypto.GetNonZeroBytes(data);
  174. }
  175. var result = new StringBuilder(maxSize);
  176. foreach (byte b in data)
  177. {
  178. result.Append(chars[b % (chars.Length)]);
  179. }
  180. return result.ToString();
  181. }
  182. }
  183. // Class Token Hash Algorithm
  184. public class PasswordHash
  185. {
  186. /// <summary>
  187. /// Functions: This class generates hases for password and verify hashed password with hashed password saved in database,
  188. /// Verification process purposefully delays to give the hacker a shitfull of pain
  189. /// </summary>
  190. static Random rnd = new Random();
  191. public const int SaltByteSize = 24;
  192. public const int HashByteSize = 20; // to match the size of the PBKDF2-HMAC-SHA-1 hash
  193. // public static int Pbkdf2Iterations = rnd.Next(2000, 3000); // Maruf: 21.Jun.2017
  194. public const int IterationIndex = 0;
  195. public const int SaltIndex = 1;
  196. public const int Pbkdf2Index = 2;
  197. public static string HashPassword(string password)
  198. {
  199. try
  200. {
  201. int pbkdf2Iterations = rnd.Next(2000, 3000);
  202. var cryptoProvider = new RNGCryptoServiceProvider();
  203. var salt = new byte[SaltByteSize];
  204. cryptoProvider.GetBytes(salt);
  205. var hash = GetPbkdf2Bytes(password, salt, pbkdf2Iterations, HashByteSize);
  206. return pbkdf2Iterations + "|" +
  207. Convert.ToBase64String(salt) + "|" +
  208. Convert.ToBase64String(hash);
  209. }
  210. catch (Exception ex)
  211. {
  212. throw;
  213. }
  214. }
  215. public static byte[] AES_Encrypt(byte[] bytesToBeEncrypted, byte[] passwordBytes)
  216. {
  217. byte[] encryptedBytes = null;
  218. // Set your salt here, change it to meet your flavor:
  219. // The salt bytes must be at least 8 bytes.
  220. byte[] saltBytes = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };
  221. using (MemoryStream ms = new MemoryStream())
  222. {
  223. using (RijndaelManaged AES = new RijndaelManaged())
  224. {
  225. AES.KeySize = 256;
  226. AES.BlockSize = 128;
  227. var key = new Rfc2898DeriveBytes(passwordBytes, saltBytes, 1000);
  228. AES.Key = key.GetBytes(AES.KeySize / 8);
  229. AES.IV = key.GetBytes(AES.BlockSize / 8);
  230. AES.Mode = CipherMode.CBC;
  231. using (var cs = new CryptoStream(ms, AES.CreateEncryptor(), CryptoStreamMode.Write))
  232. {
  233. cs.Write(bytesToBeEncrypted, 0, bytesToBeEncrypted.Length);
  234. cs.Close();
  235. }
  236. encryptedBytes = ms.ToArray();
  237. }
  238. }
  239. return encryptedBytes;
  240. }
  241. public static byte[] AES_Decrypt(byte[] bytesToBeDecrypted, byte[] passwordBytes)
  242. {
  243. byte[] decryptedBytes = null;
  244. // Set your salt here, change it to meet your flavor:
  245. // The salt bytes must be at least 8 bytes.
  246. byte[] saltBytes = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };
  247. using (MemoryStream ms = new MemoryStream())
  248. {
  249. using (RijndaelManaged AES = new RijndaelManaged())
  250. {
  251. AES.KeySize = 256;
  252. AES.BlockSize = 128;
  253. var key = new Rfc2898DeriveBytes(passwordBytes, saltBytes, 1000);
  254. AES.Key = key.GetBytes(AES.KeySize / 8);
  255. AES.IV = key.GetBytes(AES.BlockSize / 8);
  256. AES.Mode = CipherMode.CBC;
  257. using (var cs = new CryptoStream(ms, AES.CreateDecryptor(), CryptoStreamMode.Write))
  258. {
  259. cs.Write(bytesToBeDecrypted, 0, bytesToBeDecrypted.Length);
  260. cs.Close();
  261. }
  262. decryptedBytes = ms.ToArray();
  263. }
  264. }
  265. return decryptedBytes;
  266. }
  267. public static string EncryptText(string input, string password = "E6t187^D43%F")
  268. {
  269. // Get the bytes of the string
  270. byte[] bytesToBeEncrypted = Encoding.UTF8.GetBytes(input);
  271. byte[] passwordBytes = Encoding.UTF8.GetBytes(password);
  272. // Hash the password with SHA256
  273. passwordBytes = SHA256.Create().ComputeHash(passwordBytes);
  274. byte[] bytesEncrypted = AES_Encrypt(bytesToBeEncrypted, passwordBytes);
  275. string result = Convert.ToBase64String(bytesEncrypted);
  276. return result;
  277. }
  278. public static string DecryptText(string input, string password = "E6t187^D43%F")
  279. {
  280. // Get the bytes of the string
  281. byte[] bytesToBeDecrypted = Convert.FromBase64String(input);
  282. byte[] passwordBytes = Encoding.UTF8.GetBytes(password);
  283. passwordBytes = SHA256.Create().ComputeHash(passwordBytes);
  284. byte[] bytesDecrypted = AES_Decrypt(bytesToBeDecrypted, passwordBytes);
  285. string result = Encoding.UTF8.GetString(bytesDecrypted);
  286. return result;
  287. }
  288. public static bool ValidatePassword(string password, string correctHash)
  289. {
  290. try
  291. {
  292. char[] delimiter = { '|' };
  293. var split = correctHash.Split(delimiter);
  294. var iterations = Int32.Parse(split[IterationIndex]);
  295. var salt = Convert.FromBase64String(split[SaltIndex]);
  296. var hash = Convert.FromBase64String(split[Pbkdf2Index]);
  297. var testHash = GetPbkdf2Bytes(password, salt, iterations, hash.Length);
  298. return SlowEquals(hash, testHash);
  299. }
  300. catch (Exception ex)
  301. {
  302. throw;
  303. }
  304. }
  305. private static bool SlowEquals(byte[] a, byte[] b)
  306. {
  307. try
  308. {
  309. var diff = (uint)a.Length ^ (uint)b.Length;
  310. for (int i = 0; i < a.Length && i < b.Length; i++)
  311. {
  312. diff |= (uint)(a[i] ^ b[i]);
  313. }
  314. return diff == 0;
  315. }
  316. catch (Exception ex)
  317. {
  318. throw;
  319. }
  320. }
  321. private static byte[] GetPbkdf2Bytes(string password, byte[] salt, int iterations, int outputBytes)
  322. {
  323. try
  324. {
  325. var pbkdf2 = new Rfc2898DeriveBytes(password, salt) { IterationCount = iterations };
  326. return pbkdf2.GetBytes(outputBytes);
  327. }
  328. catch (Exception ex)
  329. {
  330. throw;
  331. }
  332. }
  333. }

StronglyTypeModel

Add the following code in StronglyTypeModel sub folder. Each class should have separate class file.

  1. //For Employee Will be call from Web API controller Class
  2. public class EmployeeUserModel
  3. {
  4. public int EmployeeId { get; set; }
  5. public string EmployeeName { get; set; }
  6. public string EmployeeEmail { get; set; }
  7. public string EmployeeMobileNumber { get; set; }
  8. public string EmployeeAddress { get; set; }
  9. public int UserId { get; set; }
  10. public string FullName { get; set; }
  11. public string UserName { get; set; }
  12. public string PasswordNo { get; set; }
  13. }
  14. // For Login Will be call from Web API controller Class
  15. public class LoginModel
  16. {
  17. public int UserId { get; set; }
  18. public string FullName { get; set; }
  19. public string LoginName { get; set; }
  20. public string PasswordNo { get; set; }
  21. public int EmployeeId { get; set; }
  22. public string EmployeeName { get; set; }
  23. }

Step 6

Now create a ADO.NET Entity Data Model by right clicking on Model folder give the model name as "DbModel" after providing all of your server credentials name the entity (connectionString name) as "Entity." It's mandatory to use specifyed naming conventions.

ASP.NET

Step 7

Now add Web API Controller Class under the controller folder.

Code Snippet for Web API Controller Class

Here note that you will get your token from API Response header portion. I have used POST MAN for this request. You can find your generated token in POST MAN Response header part.

  1. // For Employee Controller
  2. public class EmployeeController : ApiController
  3. {
  4. private readonly IEmployeeRepository _employeeRepository;
  5. public EmployeeController()
  6. {
  7. this._employeeRepository = new EmployeeRepository();
  8. }
  9. public EmployeeController(IEmployeeRepository employeeRepository)
  10. {
  11. this._employeeRepository = employeeRepository;
  12. }
  13. //Can not access data unknown user without Valid Token
  14. [ApiAuthorize] // use this annotation for authentication I have used only here
  15. [HttpGet, ActionName("GetAllEmployeesWithToken")]
  16. public HttpResponseMessage GetAllEmployeesWithToken()
  17. {
  18. var data = _employeeRepository.GetAllEmployees();
  19. var formatter = RequestFormat.JsonFormaterString();
  20. return Request.CreateResponse(HttpStatusCode.OK, data, formatter);
  21. }
  22. //Can access data unknown user without Valid Token
  23. [AllowAnonymous]
  24. [HttpGet, ActionName("GetAllEmployeesWithOutToken")]
  25. public HttpResponseMessage GetAllEmployeesWithOutToken()
  26. {
  27. var data = _employeeRepository.GetAllEmployees();
  28. var formatter = RequestFormat.JsonFormaterString();
  29. return Request.CreateResponse(HttpStatusCode.OK, data, formatter);
  30. }
  31. }
  32. // For Login Controller
  33. public class LoginController : ApiController
  34. {
  35. private readonly ILoginRepository _loginRepository;
  36. private readonly IUserRepository _userRepository;
  37. public LoginController()
  38. {
  39. _userRepository = new UserRepository();
  40. this._loginRepository = new LoginRepository();
  41. }
  42. [HttpPost, ActionName("UserLogin")]
  43. public HttpResponseMessage UserLogin([FromBody] Models.StronglyType.EmployeeUserModel objEmployeeUserModel)
  44. {
  45. try
  46. {
  47. var formatter = RequestFormat.JsonFormaterString();
  48. if (string.IsNullOrEmpty(objEmployeeUserModel.UserName))
  49. {
  50. return Request.CreateResponse(HttpStatusCode.NotAcceptable, new Confirmation { ResponseStatus = "error", Message = "User Name can not be empty" }, formatter);
  51. }
  52. if (string.IsNullOrEmpty(objEmployeeUserModel.PasswordNo))
  53. {
  54. return Request.CreateResponse(HttpStatusCode.NotAcceptable, new Confirmation { ResponseStatus = "error", Message = "password can not be empty" }, formatter);
  55. }
  56. var userInfo = _userRepository.GetUserByLoginName(objEmployeeUserModel.UserName);
  57. if (userInfo != null)
  58. {
  59. var login = _loginRepository.LoginInformation(objEmployeeUserModel.UserName, objEmployeeUserModel.PasswordNo);
  60. if (login != null)
  61. {
  62. var oResponse = Request.CreateResponse(HttpStatusCode.OK,
  63. new Confirmation { ResponseStatus = "success", Message = "Login Successfully", ResponseData = userInfo }, formatter);
  64. if (_loginRepository.IsTokenAlreadyExists(userInfo.UserId))
  65. {
  66. _loginRepository.DeleteGenerateToken(userInfo.UserId);
  67. return GenerateandSaveToken(userInfo.UserId, oResponse);
  68. }
  69. else
  70. {
  71. return GenerateandSaveToken(userInfo.UserId, oResponse);
  72. }
  73. }
  74. return Request.CreateResponse(HttpStatusCode.Forbidden,
  75. new Confirmation { ResponseStatus = "error", Message = "Please enter valid username or password" }, formatter);
  76. }
  77. return Request.CreateResponse(HttpStatusCode.Forbidden,
  78. new Confirmation { ResponseStatus = "error", Message = "Please enter valid username or password" }, formatter);
  79. }
  80. catch (Exception ex)
  81. {
  82. var formatter = RequestFormat.JsonFormaterString();
  83. return Request.CreateResponse(HttpStatusCode.OK, new Confirmation { ResponseStatus = "error", Message = "Login is not succesfull" }, formatter);
  84. }
  85. }
  86. [NonAction]
  87. private HttpResponseMessage GenerateandSaveToken(int userId, HttpResponseMessage response)
  88. {
  89. try
  90. {
  91. var issuedOn = DateTime.Now;
  92. var newToken = _loginRepository.GenerateToken(userId, issuedOn);
  93. var token = new TokenManager();
  94. token.TokenID = 0;
  95. token.TokenKey = newToken;
  96. token.IssuedOn = issuedOn;
  97. token.ExpiresOn = DateTime.Now.AddMinutes(Convert.ToInt32(ConfigurationManager.AppSettings["TokenExpiry"]));
  98. token.CreatedOn = DateTime.Now;
  99. token.UserId = userId;
  100. var result = _loginRepository.InsertToken(token);
  101. if (result == 1)
  102. {
  103. response.Headers.Add("Token", newToken);
  104. response.Headers.Add("TokenExpiry", ConfigurationManager.AppSettings["TokenExpiry"]);
  105. response.Headers.Add("Access-Control-Expose-Headers", "Token,TokenExpiry");
  106. return response;
  107. }
  108. var message = new HttpResponseMessage(HttpStatusCode.NotAcceptable);
  109. message.Content = new StringContent("Error in Creating Token");
  110. return message;
  111. }
  112. catch (Exception ex)
  113. {
  114. var formatter = RequestFormat.JsonFormaterString();
  115. return Request.CreateResponse(HttpStatusCode.InternalServerError, new Confirmation { ResponseStatus = "error", Message = "Cannot generate and Save Token" }, formatter);
  116. }
  117. }
  118. }

Step 7

As you have seen above I have not used RESTful API here, so you might get 404 error while you attempt to send a request from Post Man. To solve this issue, paste the following code in your WebApiConfig.cs file under App_Start folder. It will allow you to have multipule http verbs in controller class.

Code Snippet for WebApiConfig.cs

  1. config.Routes.MapHttpRoute(
  2. name: "ControllersWithAction",
  3. routeTemplate: "{controller}/{action}/{id}",
  4. defaults: new { id = RouteParameter.Optional }
  5. );

Final Step

Just build your project and send request from Post Man as json data format.

Post Man request format

ASP.NET

Post Man response format with token

ASP.NET

Code Snippet for json request format

  1. {
  2. "UserName": "admin",
  3. "PasswordNo": "123456"
  4. }

Access your data in json request format through POST MAN

See the following image - add your Token in Post Man request header part when you attempt to hit the controller class:

ASP.NET

Points of Interest

When I attempt to write any topic, I feel a wonderful excitement. I have to go through a with range on RND. I wish to spread my knowledge with technology lovers. It really feels good. I always try to describe the technology in a simple and easy way.