using Microsoft.IdentityModel.Tokens;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.IO;
using System.Linq;
using System.Security.Claims;
using System.Text;
namespace key4intranet.authentication.Providers.Jwt
{
public class JwtTokenProvider : ITokenProvider
{
public static byte[] SignatureKey { get; } = Encoding.ASCII.GetBytes(Guid.NewGuid().ToString());
public static string Issuer { get; set; } = "https://api.key4intranet.key4events.com";
///
/// Create a JWT with private and public claims
///
/// private claims
/// public claims
/// token
public string CreateToken(IDictionary privateClaims, IDictionary publicClaims)
{
throw new NotImplementedException();
}
///
/// Create a JWT with list of private claim
///
/// claims
/// encrypt token
public string CreateToken(IDictionary claims)
{
//private claims can't not be empty
if (claims == null || claims.Count == 0)
throw new IOException($"private claims can't be null or empty.");
var tokenDescriptor = (new SecurityTokenDescriptor()
{
Issuer = Issuer,
Expires = DateTime.UtcNow.AddMinutes(120),
SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(SignatureKey), SecurityAlgorithms.HmacSha256Signature),
Subject = new ClaimsIdentity()
});
// Registrered claims
foreach (var item in claims)
{
// identifier
if (new List() { "name", "id" }.Contains(item.Key.ToLower())) tokenDescriptor.Subject.AddClaim(new Claim(ClaimTypes.Name, item.Value.ToString()));
// roles
else if (new List() { "role", "roles" }.Contains(item.Key.ToLower()))
if (item.Value is IEnumerable roles)
foreach (string role in roles)
tokenDescriptor.Subject.AddClaim(new Claim(ClaimTypes.Role, role));
else
tokenDescriptor.Subject.AddClaim(new Claim(ClaimTypes.Role, item.Value.ToString()));
// issuer
else if (new List() { "iss", "issuer" }.Contains(item.Key.ToLower())) tokenDescriptor.Issuer = item.Value.ToString();
//audience
else if (new List() { "aud", "audience" }.Contains(item.Key.ToLower())) tokenDescriptor.Audience = item.Value.ToString();
}
var handler = new JwtSecurityTokenHandler();
var token = handler.CreateToken(tokenDescriptor);
return handler.WriteToken(token);
}
///
/// Get claims from token
///
/// token
/// List of claims
public IDictionary ReadClaims(string token)
{
if (token == null)
throw new ArgumentNullException("Token is null.");
var handler = new JwtSecurityTokenHandler();
if (!handler.CanReadToken(token))
throw new ArgumentException("Can't read token.");
var jwtToken = handler.ReadJwtToken(token);
return (IDictionary)jwtToken.Claims.ToDictionary(c => c.Type, c => (object)c.Value);
}
///
/// For JWT => Bearer extention will validate token
///
/// jwt token
/// true if valid
public bool ValidateToken(string token)
{
throw new NotImplementedException();
}
}
}