using System; using System.Security.Claims; using System.Collections.Generic; using AuthenticationService.Models; using Microsoft.IdentityModel.Tokens; using System.IdentityModel.Tokens.Jwt; namespace AuthenticationService.Managers { public class JWTService : IAuthService { #region Members /// /// The secret key we use to encrypt out token with. /// public string SecretKey { get; set; } #endregion #region Constructor public JWTService(string secretKey) { SecretKey = secretKey; } #endregion #region Public Methods /// /// Validates whether a given token is valid or not, and returns true in case the token is valid otherwise it will return false; /// /// /// public bool IsTokenValid(string token) { if (string.IsNullOrEmpty(token)) throw new ArgumentException("Given token is null or empty."); TokenValidationParameters tokenValidationParameters = GetTokenValidationParameters(); JwtSecurityTokenHandler jwtSecurityTokenHandler = new JwtSecurityTokenHandler(); try { ClaimsPrincipal tokenValid = jwtSecurityTokenHandler.ValidateToken(token, tokenValidationParameters, out SecurityToken validatedToken); return true; } catch (Exception) { return false; } } /// /// Generates token by given model. /// Validates whether the given model is valid, then gets the symmetric key. /// Encrypt the token and returns it. /// /// /// Generated token. public string GenerateToken(IAuthContainerModel model) { if (model == null || model.Claims == null || model.Claims.Length == 0) throw new ArgumentException("Arguments to create token are not valid."); SecurityTokenDescriptor securityTokenDescriptor = new SecurityTokenDescriptor { Subject = new ClaimsIdentity(model.Claims), Expires = DateTime.UtcNow.AddMinutes(Convert.ToInt32(model.ExpireMinutes)), SigningCredentials = new SigningCredentials(GetSymmetricSecurityKey(), model.SecurityAlgorithm) }; JwtSecurityTokenHandler jwtSecurityTokenHandler = new JwtSecurityTokenHandler(); SecurityToken securityToken = jwtSecurityTokenHandler.CreateToken(securityTokenDescriptor); string token = jwtSecurityTokenHandler.WriteToken(securityToken); return token; } /// /// Receives the claims of token by given token as string. /// /// /// Pay attention, one the token is FAKE the method will throw an exception. /// /// /// IEnumerable of claims for the given token. public IEnumerable GetTokenClaims(string token) { if (string.IsNullOrEmpty(token)) throw new ArgumentException("Given token is null or empty."); TokenValidationParameters tokenValidationParameters = GetTokenValidationParameters(); JwtSecurityTokenHandler jwtSecurityTokenHandler = new JwtSecurityTokenHandler(); try { ClaimsPrincipal tokenValid = jwtSecurityTokenHandler.ValidateToken(token, tokenValidationParameters, out SecurityToken validatedToken); return tokenValid.Claims; } catch (Exception ex) { throw ex; } } #endregion #region Private Methods private SecurityKey GetSymmetricSecurityKey() { byte[] symmetricKey = Convert.FromBase64String(SecretKey); return new SymmetricSecurityKey(symmetricKey); } private TokenValidationParameters GetTokenValidationParameters() { return new TokenValidationParameters() { ValidateIssuer = false, ValidateAudience = false, IssuerSigningKey = GetSymmetricSecurityKey(), ValidateLifetime = true }; } #endregion } }