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(); } } }