el

How to secure web API using JToken

Sunday, October 25, 2020

When we are developing Web API for mobile application, it should be secure and recognize the authorize user. Create a token for individual user at the time of log in to your application. Pass this token in every API call. What is JToken JToken is a generic representation of a JSON string or object, for example X-Token: nbmnbmn {"myAccDetails":{"pAccNo":"10000”}}   The following steps to add JToken to your Web API.   Step:1 Create a Token class which will encrypt and decrypt your token using System; using System.Collections.Generic; using System.Linq; using System.Security.Cryptography.X509Certificates; using WebAPIAuthenitication.Helpers;   namespace myApplication.Security { public class Token { public Token(string userId, string fromIP) { UserId = userId; IP = fromIP; }   public string UserId { get; private set; } public string IP { get; private set; }   public string Encrypt() { CryptographyHelper cryptographyHelper = new CryptographyHelper(); X509Certificate2 certificate = cryptographyHelper.GetX509Certificate("CN=WebAPI-Token"); return cryptographyHelper.Encrypt(certificate, this.ToString()); }   public override string ToString() { return String.Format("UserId={0};IP={1}", this.UserId, this.IP); }   public static Token Decrypt(string encryptedToken) { CryptographyHelper cryptographyHelper = new CryptographyHelper(); X509Certificate2 certificate = cryptographyHelper.GetX509Certificate("CN=WebAPI-Token"); string decrypted = cryptographyHelper.Decrypt(certificate, encryptedToken);   //Splitting it to dictionary Dictionary<string, string> dictionary = decrypted.ToDictionary(); return new Token(dictionary["UserId"], dictionary["IP"]); } } }   NOTE: Here I have create my own CryptographyHelper for encrypt and decrypt the inputs Step:2 Create your Token Inspector class which will check the token   using System; using System.Collections.Generic; using System.Linq; using System.Net.Http; using System.Threading.Tasks; using System.Threading; using System.Net; using System.Security.Cryptography.X509Certificates; using WebAPIAuthenitication.Helpers;   namespace myApplication.Security { public class TokenInspector : DelegatingHandler { protected override Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { const string TOKEN_NAME = "X-Token";   if (request.Headers.Contains(TOKEN_NAME)) { string encryptedToken = request.Headers.GetValues(TOKEN_NAME).First(); try { Token token = Token.Decrypt(encryptedToken); bool isValidUserId = IdentityStore.IsValidUserId(token.UserId); bool requestIPMatchesTokenIP = token.IP.Equals(request.GetClientIP());   if (!isValidUserId || !requestIPMatchesTokenIP) { HttpResponseMessage reply = request.CreateErrorResponse(HttpStatusCode.Unauthorized, "Invalid indentity or client machine."); var taskSource = new TaskCompletionSource(); taskSource.SetResult(reply); return taskSource.Task; //return Task.Factory.FromAsync(reply,cancellationToken); } } catch (Exception ex) { HttpResponseMessage reply = request.CreateErrorResponse(HttpStatusCode.Unauthorized, "Invalid token."); var taskSource = new TaskCompletionSource(); taskSource.SetResult(reply); return taskSource.Task; } } else { HttpResponseMessage reply = request.CreateErrorResponse(HttpStatusCode.Unauthorized, "Request is missing authorization token."); var taskSource = new TaskCompletionSource(); taskSource.SetResult(reply); return taskSource.Task; }   var response=  base.SendAsync(request, cancellationToken); return response; }   } } NOTE: I have create a class IdentityStore which will check valid user id from my database. Step:3 Add Newtonsoft.Json.dll to your project reference, if it is not added. Step:4 Create your Web API method   using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.Http; using System.Net.Http.Headers; using System.Text; using System.Web.Configuration; using System.Web.Http; using myBusinessService.Models; using myBusinessService.Security; using Newtonsoft.Json; using Newtonsoft.Json.Linq;     namespace myApplication.Controllers { public class eAccountController : ApiController {   [HttpPost] public HttpResponseMessage GetAccountDetails([FromBody]JToken pJToken) { try { JToken jUser = pJToken["myAccDetails"]; String AccountNumber = Convert.ToString(jUser["pAccNo"]);   // retrieve your data from your database // convert your data to JsonResponse var result = GetAccountDetailsJsonResponse(data from database);   // Return your JsonResponse (result)     return result; } catch (Exception ex) { throw new Exception(ex.ToString()); return null; } } public static HttpResponseMessage GetAccountDetailsJsonResponse (object Data) { try { String Order = JsonConvert.SerializeObject(Data);   Dictionary<string, object> dictOrderDetails = new Dictionary<string, object>(); dictOrderDetails.Add("Orders", Data);   var str = DictionaryToJson(dictOrderDetails); HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK); response.Content = new StringContent(str, Encoding.UTF8, "text/plain");   return response; } catch (Exception ex) { throw new Exception(ex.ToString()); return null; } } } } This is all about your code. Now Build your application and run. Check your API in POSTMAN.

No items found.