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<HttpResponseMessage> 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<HttpResponseMessage>();
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<HttpResponseMessage>();
taskSource.SetResult(reply);
return taskSource.Task;
}
}
else
{
HttpResponseMessage reply = request.CreateErrorResponse(HttpStatusCode.Unauthorized, "Request is missing authorization token.");
var taskSource = new TaskCompletionSource<HttpResponseMessage>();
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.