using System; using System.IdentityModel.Tokens.Jwt; using Microsoft.IdentityModel.Tokens; using xCommons.Extensions; using xCommons.Providers; using xExceptions.Constants; using xIdentityModels.Configurations; using xIdentityModels.Extensions; using xIdentityModels.Models; using xIds.Interfaces; namespace xIds.Helpers { public class XIdentityHelper : IXIdentityHelper { private readonly XIdentityConfiguration configurations; private readonly JwtSecurityTokenHandler tokenHandler; private readonly XValidationProvider dataValidationHelper; public XIdentityHelper( XIdentityConfiguration configurations, XValidationProvider dataValidationHelper ) { // this.configurations = configurations; this.tokenHandler = new JwtSecurityTokenHandler(); this.dataValidationHelper = dataValidationHelper; } // #region Configuration Parser ... /// /// Generate a Key for Signing JWT Tokens /// /// public SymmetricSecurityKey GetTokenSecretKey() { // dataValidationHelper .NotEmpty(configurations.IdentitySecretKey); // var result = new SymmetricSecurityKey(configurations .IdentitySecretKey.ToBytes()); // return result; } /// /// Generate Security Token Signing Key /// /// public SigningCredentials GetTokenSigningCredentials() { // var key = GetTokenSecretKey(); dataValidationHelper .NotNull(key); // var result = new SigningCredentials(key, SecurityAlgorithms.HmacSha256); // return result; } /// /// Get Token Validation Parameters /// /// public TokenValidationParameters GetTokenValidationParams() { // var key = GetTokenSecretKey(); var issuer = configurations.IdentityIssuer; var audience = configurations.IdentityAudience; // dataValidationHelper .NotNull(key); dataValidationHelper .NotEmpty(issuer, audience); // var result = new TokenValidationParameters { ValidIssuer = issuer, ValidAudience = audience, ValidateLifetime = true, IssuerSigningKey = key }; // return result; } /// /// Get Account Lockout Time Span after Max Fail Reached /// /// public TimeSpan GetLockoutTimeSpan() { // dataValidationHelper .NotNull(configurations.Policy, configurations.Policy.Lockout); // var timeSpanString = configurations.Policy.Lockout.LockoutTimeSpanProvider; dataValidationHelper .NotEmpty(timeSpanString); // var mExpireValue = 0; var mExpireValueStr = timeSpanString.GetDigits(); var mExpireUnit = timeSpanString.Replace(mExpireValueStr, ""); dataValidationHelper .NotEmpty(mExpireUnit); dataValidationHelper .NotEmpty(mExpireValueStr); // var isParsed = int.TryParse(mExpireValueStr, out mExpireValue); // switch (mExpireUnit) { case "d": return TimeSpan.FromDays(mExpireValue); case "h": return TimeSpan.FromHours(mExpireValue); case "m": return TimeSpan.FromMinutes(mExpireValue); case "s": return TimeSpan.FromSeconds(mExpireValue); case "ms": default: return TimeSpan.FromMilliseconds(mExpireValue); } } /// /// Generate Security Token Descriptor for Tokenize another /// /// public SecurityTokenDescriptor GetActionTokenDescriptor() { // dataValidationHelper .NotNull(configurations); // var issuer = configurations.IdentityIssuer; var audience = configurations.IdentityAudience; dataValidationHelper .NotEmpty(issuer, audience); // var expDate = GetActionTokenExpirationDate(); var signingCreds = GetTokenSigningCredentials(); dataValidationHelper .NotNull(expDate, signingCreds); // var descriptor = new SecurityTokenDescriptor { Issuer = issuer, Audience = audience, Expires = expDate, SigningCredentials = signingCreds }; // return descriptor; } /// /// Get Action Token Expiration Date /// /// public DateTime GetActionTokenExpirationDate() { // dataValidationHelper .NotNull(configurations); // var expDateProvider = configurations .ActionTokenExpirationDateProvider; dataValidationHelper .NotEmpty(expDateProvider); // var result = GetExpirationTime(expDateProvider); dataValidationHelper .NotNull(result); // return result; } #endregion // #region Action Token Handlers ... public bool ValidateToken(string token) { // // Validate Args ... dataValidationHelper .NotEmpty(token); dataValidationHelper .NotNull(tokenHandler); // // Prepare Requirements ... var tokenValidationParams = GetTokenValidationParams(); dataValidationHelper .NotNull(tokenValidationParams); // var result = token .ValidateToken(tokenHandler, tokenValidationParams); // return result; } /// /// Converts a Token string to SecurityToken instance /// /// /// public SecurityToken ToSecurityToken(string token) { // dataValidationHelper .NotEmpty(token); // // Validate token ... var isTokenValid = ValidateToken(token); if (!isTokenValid) { XException.InvalidToken.Throw(); } // // Prepare and Validate Requirements ... var tokenValidationParams = GetTokenValidationParams(); dataValidationHelper .NotNull(tokenHandler, tokenValidationParams); // var result = token .ToSecurityToken(tokenHandler, tokenValidationParams); dataValidationHelper .NotNull(result); // return result; } /// /// Convert an ActionRequest to Token Object /// /// /// public SecurityToken ToSecurityToken(XActionRequestToken request) { // var tokenDescriptor = GetActionTokenDescriptor(); // dataValidationHelper.NotNull(request, tokenHandler, tokenDescriptor); // var result = request.ToJwtToken(tokenHandler, tokenDescriptor); // return result; } /// /// Retrieve a Token Exiration Date /// /// /// public DateTime GetTokenExpirationDate(string token) { // var tokenObj = ToSecurityToken(token); dataValidationHelper.NotNull(tokenObj); // var result = tokenObj.ValidTo; // return result; } public XActionRequestToken ParseActionRequestToken(string token) { // dataValidationHelper .NotEmpty(token); // // Validate token ... var isTokenValid = ValidateToken(token); if (!isTokenValid) { XException.InvalidToken.Throw(); } // // Prepare and Validate Requirements ... var tokenValidationParams = GetTokenValidationParams(); dataValidationHelper .NotNull(tokenHandler, tokenValidationParams); // var result = token .ParseActionRequestToken(tokenHandler, tokenValidationParams); dataValidationHelper .NotNull(result); // return result; } /// /// Convert a JWT Security Token Object to /// it's String Representation /// /// /// public string ToTokenString(JwtSecurityToken token) { // dataValidationHelper.NotNull(token); // var result = tokenHandler .WriteToken(token); // return result; } /// /// Convert an Action Token Object to it's String Representation /// /// /// public string ToTokenString(SecurityToken token) { // // Validate Args ... dataValidationHelper .NotNull(token, tokenHandler); // // Generate and return Result ... var result = token.ToTokenString(tokenHandler); dataValidationHelper .NotEmpty(result); // return result; } #endregion // #region Private Actions ... /// /// Calculating Date Difference Provider String /// and Generate Date based on UTC Time /// /// /// private DateTime GetExpirationTime(string expirationProvider) { // dataValidationHelper .NotEmpty(expirationProvider); // var mExpireValue = 0; var mExpireValueStr = expirationProvider.GetDigits(); var mExpireUnit = expirationProvider.Replace(mExpireValueStr, ""); dataValidationHelper .NotEmpty(mExpireUnit); dataValidationHelper .NotEmpty(mExpireValueStr); // var isParsed = int.TryParse(mExpireValueStr, out mExpireValue); // switch (mExpireUnit) { case "d": return DateTime.UtcNow.AddDays(mExpireValue); case "h": return DateTime.UtcNow.AddHours(mExpireValue); case "m": return DateTime.UtcNow.AddMinutes(mExpireValue); case "s": return DateTime.UtcNow.AddSeconds(mExpireValue); case "ms": default: return DateTime.UtcNow.AddMilliseconds(mExpireValue); } } #endregion } }