Create a TokenFactory class that creates an encrypted token with the Windows authenticated username:
public class TokenFactory
{
public static Aes aes = Aes.Create();
public static string GenerateToken(string UserName)
{
//Get the required values...
TokenDetails encrytionData = new TokenDetails
{
UserName = uName,
Role = rName,
SecretKey = sKey,
Date = DateTime.Now,
Interval = duration
};
//To Do: Generate with Cryptography encryption logic.
var jsonSerialize = JsonConvert.SerializeObject(encrytionData);
byte[] encrypted = Cryptography.Encrypt(jsonSerialize, aes.Key, aes.IV);
var authToken = Convert.ToBase64String(encrypted);
return authToken;
}
public static bool ValidateToken(string authToken)
{
bool isValidated;
if (!String.IsNullOrEmpty(authToken))
{
var bytarr = Convert.FromBase64String(authToken);
// Decrypt the bytes to a string.
string dcryptToken = Cryptography.Decrypt(bytarr, aes.Key, aes.IV);
var obj = JsonConvert.DeserializeObject<TokenDetails>(dcryptToken);
TimeSpan timeSpan = DateTime.Now - obj.Date;
if (timeSpan.TotalMinutes > CommonUtil.Duration)
{
isValidated = false;
}
else
{
isValidated = true;
}
}
else
{
isValidated = false;
}
return isValidated;
}
public static string GetUserFromToken(string authToken)
{
var bytarr = Convert.FromBase64String(authToken);
// Decrypt the bytes to a string.
string dcryptToken = Cryptography.Decrypt(bytarr, aes.Key, aes.IV);
var obj = JsonConvert.DeserializeObject<TokenDetails>(dcryptToken);
return Convert.ToString(obj.UserName);
}
}
Below is TokenDetails class:
public class TokenDetails
{
public DateTime Date { get; set; }
public string SecretKey { get; set; }
public string Role { get; set; }
public string UserName { get; set; }
public int Interval { get; set; }
}
Create a RequestFilter that will inherit ActionFilterAttribute to authorize any request using the [RequestFilter] attribute:
public class RequestFilter : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext context)
{
Microsoft.AspNetCore.Http.IHeaderDictionary headers = context.HttpContext.Request.Headers;
var user = context.HttpContext.User.Identity.Name;
bool IsValidated = false;
string token = string.Empty;
if (CheckValidHeaders(context))
{
if (context.HttpContext.Request.Headers.ContainsKey("token"))
{
token = context.HttpContext.Request.Headers["token"].ToString();
IsValidated = TokenFactory.ValidateToken(token, user);
}
}
if (!IsValidated)
{
if (user.Equals(TokenFactory.GetUserFromToken(token)))
{
token = TokenFactory.GenerateToken(user);
context.HttpContext.Request.Headers.Remove("token");
context.HttpContext.Request.Headers.Add("token", token);
}
else
{
//Return UnAuthorized if current Windows User is not same as the one encrypted in token.
context.Result = new UnauthorizedResult();
}
}
}
public override void OnActionExecuted(ActionExecutedContext context)
{
var token = Convert.ToString(context.HttpContext.Request.Headers["token"]);
context.HttpContext.Response.Headers.Add("token", token);
}
private bool CheckValidHeaders(ActionExecutingContext context)
{
if (String.IsNullOrEmpty(context.HttpContext.Request.Headers["token"]))
{
return false;
}
return true;
}
}
Sample Controller implementation to fetch the token:
[ApiController]
public class UserController : ControllerBase
{
// GET: api/User
[Route("User")]
[Authorize]
[HttpGet]
public IActionResult GetUser()
{
var user = HttpContext.User.Identity.Name;
string token = TokenFactory.GenerateToken(user);
//bool isValid = TokenFactory.ValidateToken(token, user);
return Ok(token);
}
}
Use the [Authorize] attribute if you’ve also enabled Anonymous Authentication to allow OPTIONS request. This is explained here in further detail.
You can Authorize your users with the [RequestFilter] to filter out the Unauthorized candidates.
[RequestFilter]
[ApiController]
[Authorize]
public class AppraisalsHomeController : ControllerBase
{
//To Do...
}