public void JwtPalyoad_Claims() { List<string> errors = new List<string>(); var jwtPayload = new JwtPayload(); // multiple audiences foreach (string aud in IdentityUtilities.DefaultAudiences) { jwtPayload.AddClaim(new Claim(JwtRegisteredClaimNames.Aud, aud)); } string encodedPayload = jwtPayload.Base64UrlEncode(); var deserializedPayload = JwtPayload.Base64UrlDeserialize(encodedPayload); if (!IdentityComparer.AreEqual(jwtPayload, deserializedPayload)) { errors.Add("!IdentityComparer.AreEqual(jwtPayload, deserializedPayload)"); } if (!IdentityComparer.AreEqual<IEnumerable<string>>(jwtPayload.Aud, IdentityUtilities.DefaultAudiences)) { errors.Add("!IdentityComparer.AreEqual<IEnumerable<string>>(jwtPayload.Aud, IdentityUtilities.DefaultAudiences)"); } TestUtilities.AssertFailIfErrors(MethodInfo.GetCurrentMethod().Name, errors); }
/// <summary> /// Decodes the string into the header, payload and signature /// </summary> /// <param name="jwtEncodedString">Base64Url encoded string.</param> internal void Decode(string jwtEncodedString) { string[] tokenParts = jwtEncodedString.Split(new char[] { '.' }, 4); if (tokenParts.Length != 3) { throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, ErrorMessages.IDX10709, "jwtEncodedString", jwtEncodedString)); } try { this.header = JwtHeader.Base64UrlDeserialize(tokenParts[0]); // if present, "typ" should be set to "JWT" or "http://openid.net/specs/jwt/1.0" string type = this.header.Typ; if (type != null) { if (!(StringComparer.Ordinal.Equals(type, JwtConstants.HeaderType) || StringComparer.Ordinal.Equals(type, JwtConstants.HeaderTypeAlt))) { throw new SecurityTokenException(string.Format(CultureInfo.InvariantCulture, ErrorMessages.IDX10702, JwtConstants.HeaderType, JwtConstants.HeaderTypeAlt, type)); } } } catch (Exception ex) { if (DiagnosticUtility.IsFatal(ex)) { throw; } throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, ErrorMessages.IDX10703, "header", tokenParts[0], jwtEncodedString), ex); } try { this.payload = JwtPayload.Base64UrlDeserialize(tokenParts[1]); } catch (Exception ex) { if (DiagnosticUtility.IsFatal(ex)) { throw; } throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, ErrorMessages.IDX10703, "payload", tokenParts[1], jwtEncodedString), ex); } // ensure signature is well-formed, GitIssue 103 if (!string.IsNullOrEmpty(tokenParts[2])) { try { Base64UrlEncoder.Decode(tokenParts[2]); } catch (Exception ex) { if (DiagnosticUtility.IsFatal(ex)) { throw; } throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, ErrorMessages.IDX10703, "signature", tokenParts[1], jwtEncodedString), ex); } } this.rawData = jwtEncodedString; this.rawHeader = tokenParts[0]; this.rawPayload = tokenParts[1]; this.rawSignature = tokenParts[2]; }
public void CreateAndValidateTokens_MultipleX5C() { List<string> errors = new List<string>(); var handler = new JwtSecurityTokenHandler(); var payload = new JwtPayload(); var header = new JwtHeader(); payload.AddClaims(ClaimSets.MultipleAudiences(IdentityUtilities.DefaultIssuer, IdentityUtilities.DefaultIssuer)); List<string> x5cs = new List<string> { "x5c1", "x5c2" }; header.Add(JwtHeaderParameterNames.X5c, x5cs); var jwtToken = new JwtSecurityToken(header, payload); var jwt = handler.WriteToken(jwtToken); var validationParameters = new TokenValidationParameters { RequireExpirationTime = false, RequireSignedTokens = false, ValidateAudience = false, ValidateIssuer = false, ValidateLifetime = false, }; SecurityToken validatedSecurityToken = null; var cp = handler.ValidateToken(jwt, validationParameters, out validatedSecurityToken); JwtSecurityToken validatedJwt = validatedSecurityToken as JwtSecurityToken; object x5csInHeader = validatedJwt.Header[JwtHeaderParameterNames.X5c]; if (x5csInHeader == null) { errors.Add("1: validatedJwt.Header[JwtHeaderParameterNames.X5c]"); } else { var list = x5csInHeader as IEnumerable<object>; if ( list == null ) { errors.Add("2: var list = x5csInHeader as IEnumerable<object>; is NULL."); } int num = 0; foreach(var str in list) { num++; if (!(str is string)) { errors.Add("3: str is not string, is:" + str.ToString()); } } if (num != x5cs.Count) { errors.Add("4: num != x5cs.Count. num: " + num.ToString() + "x5cs.Count: " + x5cs.Count.ToString()); } } // make sure we can still validate with existing logic. header = new JwtHeader(KeyingMaterial.DefaultAsymmetricSigningCreds_2048_RsaSha2_Sha2); header.Add(JwtHeaderParameterNames.X5c, x5cs); jwtToken = new JwtSecurityToken(header, payload); jwt = handler.WriteToken(jwtToken); validationParameters.IssuerSigningToken = KeyingMaterial.DefaultAsymmetricX509Token_2048; validationParameters.RequireSignedTokens = true; validatedSecurityToken = null; cp = handler.ValidateToken(jwt, validationParameters, out validatedSecurityToken); TestUtilities.AssertFailIfErrors(MethodInfo.GetCurrentMethod().Name, errors); }
/// <summary> /// Initializes a new instance of the <see cref="JwtSecurityToken"/> class where the <see cref="JwtHeader"/> contains the crypto algorithms applied to the encoded <see cref="JwtHeader"/> and <see cref="JwtPayload"/>. The jwtEncodedString is the result of those operations. /// </summary> /// <param name="header">Contains JSON objects representing the cryptographic operations applied to the JWT and optionally any additional properties of the JWT</param> /// <param name="payload">Contains JSON objects representing the claims contained in the JWT. Each claim is a JSON object of the form { Name, Value }</param> /// <param name="rawHeader">base64urlencoded JwtHeader</param> /// <param name="rawPayload">base64urlencoded JwtPayload</param> /// <param name="rawSignature">base64urlencoded JwtSignature</param> /// <exception cref="ArgumentNullException">'header' is null.</exception> /// <exception cref="ArgumentNullException">'payload' is null.</exception> /// <exception cref="ArgumentNullException">'rawSignature' is null.</exception> /// <exception cref="ArgumentException">'rawHeader' or 'rawPayload' is null or whitespace.</exception> public JwtSecurityToken(JwtHeader header, JwtPayload payload, string rawHeader, string rawPayload, string rawSignature) { if (header == null) { throw new ArgumentNullException("header"); } if (payload == null) { throw new ArgumentNullException("payload"); } if (rawSignature == null) { throw new ArgumentNullException("rawSignature"); } if (string.IsNullOrWhiteSpace(rawHeader)) { throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, ErrorMessages.IDX10002, "rawHeader")); } if (string.IsNullOrWhiteSpace(rawPayload)) { throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, ErrorMessages.IDX10002, "rawPayload")); } this.header = header; this.payload = payload; this.rawData = string.Concat(rawHeader, ".", rawPayload, ".", rawSignature); this.rawHeader = rawHeader; this.rawPayload = rawPayload; this.rawSignature = rawSignature; }
public void JwtPalyoad_Claims() { JwtPayload jwtPayload = new JwtPayload(); // multiple audiences jwtPayload.Add(JwtRegisteredClaimNames.Aud, IdentityUtilities.DefaultAudiences); string encodedPayload = jwtPayload.Encode(); JwtPayload newjwtPayload = Base64UrlEncoder.Decode(encodedPayload).DeserializeJwtPayload(); Assert.IsTrue(IdentityComparer.AreEqual(jwtPayload, newjwtPayload)); }
public void JwtPayload_Defaults() { JwtPayload jwtPayload = new JwtPayload(); List<Claim> claims = jwtPayload.Claims as List<Claim>; Assert.IsNotNull(claims, "claims as List<Claim> == null"); foreach (Claim c in jwtPayload.Claims) { Assert.Fail("jwtPayload.Claims should be empty"); } Assert.IsNotNull(jwtPayload.Aud, "jwtPayload.Aud should not be null"); foreach(string audience in jwtPayload.Aud) { Assert.Fail("jwtPayload.Aud should be empty"); } Assert.AreEqual(jwtPayload.ValidFrom, DateTime.MinValue, "jwtPayload.ValidFrom != DateTime.MinValue"); Assert.AreEqual(jwtPayload.ValidTo, DateTime.MinValue, "jwtPayload.ValidTo != DateTime.MinValue"); }
/// <summary> /// Encodes the specified email. /// </summary> /// <param name="email">The email.</param> /// <param name="certificateFilePath">The certificate file path.</param> /// <returns></returns> public static string Encode(string email, string certificateFilePath) { var utc0 = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc); var issueTime = DateTime.Now; var iat = (int)issueTime.Subtract(utc0).TotalSeconds; var exp = (int)issueTime.AddMinutes(55).Subtract(utc0).TotalSeconds; // Expiration time is up to 1 hour, but lets play on safe side var payload = new JwtPayload { iss = email, scope = "https://www.googleapis.com/auth/gan.readonly", aud = "https://accounts.google.com/o/oauth2/token", exp = exp, iat = iat }; var certificate = new X509Certificate2(certificateFilePath, "notasecret"); var privateKey = certificate.Export(X509ContentType.Cert); return JsonWebToken<JwtPayload>.Encode(payload, privateKey, JwtHashAlgorithm.RS256); }
public void GetSets() { // Aud, Claims, ValidFrom, ValidTo handled in Defaults. JwtPayload jwtPayload = new JwtPayload(); Type type = typeof(JwtPayload); PropertyInfo[] properties = type.GetProperties(); if (properties.Length != 23) { Assert.True(false, "Number of properties has changed from 23 to: " + properties.Length + ", adjust tests"); } GetSetContext context = new GetSetContext { PropertyNamesAndSetGetValue = new List <KeyValuePair <string, List <object> > > { new KeyValuePair <string, List <object> >("Actort", new List <object> { (string)null, Guid.NewGuid().ToString(), Guid.NewGuid().ToString() }), new KeyValuePair <string, List <object> >("Acr", new List <object> { (string)null, Guid.NewGuid().ToString(), Guid.NewGuid().ToString() }), new KeyValuePair <string, List <object> >("AuthTime", new List <object> { (string)null, 10, 12 }), new KeyValuePair <string, List <object> >("Azp", new List <object> { (string)null, Guid.NewGuid().ToString(), Guid.NewGuid().ToString() }), new KeyValuePair <string, List <object> >("CHash", new List <object> { (string)null, Guid.NewGuid().ToString(), Guid.NewGuid().ToString() }), new KeyValuePair <string, List <object> >("Exp", new List <object> { (string)null, 1, 0 }), new KeyValuePair <string, List <object> >("Jti", new List <object> { (string)null, Guid.NewGuid().ToString(), Guid.NewGuid().ToString() }), new KeyValuePair <string, List <object> >("Iat", new List <object> { (string)null, 10, 0 }), new KeyValuePair <string, List <object> >("Iss", new List <object> { (string)null, Guid.NewGuid().ToString(), Guid.NewGuid().ToString() }), new KeyValuePair <string, List <object> >("Nbf", new List <object> { (string)null, 1, 0 }), new KeyValuePair <string, List <object> >("Nonce", new List <object> { (string)null, Guid.NewGuid().ToString(), Guid.NewGuid().ToString() }), new KeyValuePair <string, List <object> >("Sub", new List <object> { (string)null, Guid.NewGuid().ToString(), Guid.NewGuid().ToString() }), }, Object = jwtPayload, }; TestUtilities.GetSet(context); TestUtilities.AssertFailIfErrors("JwtPayload_GetSets", context.Errors); }
public string GenerateToken(string name, string role, int userId, object validationId, string userPath, out string refreshTokenString, bool refreshTokenAsWell = false) { if (string.IsNullOrWhiteSpace(name)) { throw new ArgumentOutOfRangeException(nameof(name)); } string tokenString = null; refreshTokenString = null; if (_handler.CanWriteToken) { var signingCredentials = new SigningCredentials(_securityKey.SecurityKey, _tokenParameters.EncryptionAlgorithm); var now = _tokenParameters.ValidFrom ?? DateTime.UtcNow; var numericNow = GetNumericDate(now); var notBefore = now; var numericNotBefore = GetNumericDate(notBefore); var expiration = now.AddMinutes(_tokenParameters.AccessLifeTimeInMinutes); var numericExpiration = GetNumericDate(expiration); var header = new JwtHeader(signingCredentials); var payload = new JwtPayload { { "iss", _tokenParameters.Issuer }, { "sub", _tokenParameters.Subject }, { "aud", _tokenParameters.Audience }, { "exp", numericExpiration }, { "iat", numericNow }, { "nbf", numericNotBefore }, { "name", name }, { "jti", Guid.NewGuid().ToString("N") }, { "uid", userId }, { "uvid", validationId }, { "upath", userPath } }; if (!string.IsNullOrWhiteSpace(role)) { payload.AddClaim(new Claim("role", role)); } var accessToken = new JwtSecurityToken(header, payload); tokenString = _handler.WriteToken(accessToken); if (refreshTokenAsWell) { var refreshExpiration = expiration.AddMinutes(_tokenParameters.RefreshLifeTimeInMinutes); numericExpiration = GetNumericDate(refreshExpiration); notBefore = expiration; numericNotBefore = GetNumericDate(notBefore); payload = new JwtPayload { { "iss", _tokenParameters.Issuer }, { "sub", _tokenParameters.Subject }, { "aud", _tokenParameters.Audience }, { "exp", numericExpiration }, { "iat", numericNow }, { "nbf", numericNotBefore }, { "name", name }, { "jti", Guid.NewGuid().ToString("N") }, { "uid", userId }, { "uvid", validationId }, { "upath", userPath } }; var refreshToken = new JwtSecurityToken(header, payload); refreshTokenString = _handler.WriteToken(refreshToken); } } return(tokenString); }
/// <summary> /// Turns a token object into JWT payload /// </summary> /// <param name="token">The token</param> /// <returns>Serialized JWT payload</returns> public static string CreateJwtPayload(this Token token) { var payload = new JwtPayload( token.Issuer, token.Audience, null, token.CreationTime.UtcDateTime, token.CreationTime.AddSeconds(token.Lifetime).UtcDateTime); var amrClaims = token.Claims.Where(x => x.Type == Constants.ClaimTypes.AuthenticationMethod); var jsonClaims = token.Claims.Where(x => x.ValueType == Constants.ClaimValueTypes.Json); var scopeClaims = token.Claims.Where(x => x.ValueType == Constants.ClaimTypes.Scope); var normalClaims = token.Claims.Except(amrClaims).Except(jsonClaims); payload.AddClaims(normalClaims); // deal with amr var amrValues = amrClaims.Select(x => x.Value).Distinct().ToArray(); if (amrValues.Any()) { payload.Add(Constants.ClaimTypes.AuthenticationMethod, amrValues); } var scopeValues = scopeClaims.Select(x => x.Value).Distinct().ToArray(); if (scopeValues.Any()) { payload.Add(Constants.ClaimTypes.Scope, scopeValues); } // deal with json types // calling ToArray() to trigger JSON parsing once and so later // collection identity comparisons work for the anonymous type var jsonTokens = jsonClaims.Select(x => new { x.Type, JsonValue = JRaw.Parse(x.Value) }).ToArray(); var jsonObjects = jsonTokens.Where(x => x.JsonValue.Type == JTokenType.Object).ToArray(); var jsonObjectGroups = jsonObjects.GroupBy(x => x.Type).ToArray(); foreach (var group in jsonObjectGroups) { if (payload.ContainsKey(group.Key)) { throw new Exception(String.Format("Can't add two claims where one is a JSON object and the other is not a JSON object ({0})", group.Key)); } if (group.Skip(1).Any()) { // add as array payload.Add(group.Key, group.Select(x => x.JsonValue).ToArray()); } else { // add just one payload.Add(group.Key, group.First().JsonValue); } } var jsonArrays = jsonTokens.Where(x => x.JsonValue.Type == JTokenType.Array).ToArray(); var jsonArrayGroups = jsonArrays.GroupBy(x => x.Type).ToArray(); foreach (var group in jsonArrayGroups) { if (payload.ContainsKey(group.Key)) { throw new Exception(String.Format("Can't add two claims where one is a JSON array and the other is not a JSON array ({0})", group.Key)); } List <JToken> newArr = new List <JToken>(); foreach (var arrays in group) { var arr = (JArray)arrays.JsonValue; newArr.AddRange(arr); } // add just one array for the group/key/claim type payload.Add(group.Key, newArr.ToArray()); } var unsupportedJsonTokens = jsonTokens.Except(jsonObjects).Except(jsonArrays); var unsupportedJsonClaimTypes = unsupportedJsonTokens.Select(x => x.Type).Distinct(); if (unsupportedJsonClaimTypes.Any()) { throw new Exception(String.Format("Unsupported JSON type for claim types: {0}", unsupportedJsonClaimTypes.Aggregate((x, y) => x + ", " + y))); } return(payload.SerializeToJson()); }
public async Task <IActionResult> IssueToken() { var pemFileName = Environment.GetEnvironmentVariable(Defines.PrivateKeyFileEnvironmentVariableName) ?? throw new ApplicationException( $"\"{Defines.PrivateKeyFileEnvironmentVariableName}\" environment variable is not set or empty"); logger.LogInformation($"Reading private key from file: {pemFileName}"); var pemDataBytes = await System.IO.File.ReadAllBytesAsync(pemFileName); var pemDataString = Encoding.UTF8.GetString(pemDataBytes); // Use "-----BEGIN PRIVATE KEY-----" and "-----END PRIVATE KEY-----" headers for PKCS8 var b64 = pemDataString.Replace("-----BEGIN RSA PRIVATE KEY-----", string.Empty) .Replace("-----END RSA PRIVATE KEY-----", string.Empty) .Replace("\n", string.Empty) .Trim(); var privateKey = Convert.FromBase64String(b64); var rsa = System.Security.Cryptography.RSA.Create(); // Use rsa.ImportPkcs8PrivateKey(privateKey, out var bytesRead) for PKCS8 keys rsa.ImportRSAPrivateKey(privateKey, out var bytesRead); logger.LogInformation($"RSA private key bytes read: {bytesRead}"); var securityKey = new RsaSecurityKey(rsa); logger.LogInformation($"RSA security key size: {securityKey.KeySize} bits"); // Use preferred sign algorithm var signingCredentials = new SigningCredentials(securityKey, SecurityAlgorithms.RsaSha256); var jwtHeader = new JwtHeader(signingCredentials); const string jti = "TokenIndex"; var jwtPayload = new JwtPayload { { JwtRegisteredClaimNames.Jti, jti }, { JwtRegisteredClaimNames.Sub, "TokenSubject" }, { JwtRegisteredClaimNames.Aud, "TokenAudience" }, { "CustomClaim", "SomeData" }, }; var i = DateTimeOffset.UtcNow.ToUnixTimeSeconds(); var e = i + Defines.TokenTtl; var iat = new Claim(JwtRegisteredClaimNames.Iat, i.ToString(), ClaimValueTypes.Integer64); var exp = new Claim(JwtRegisteredClaimNames.Exp, e.ToString(), ClaimValueTypes.Integer64); jwtPayload.AddClaim(iat); jwtPayload.AddClaim(exp); var token = new JwtSecurityToken(jwtHeader, jwtPayload); var tokenHandler = new JwtSecurityTokenHandler(); var accessToken = tokenHandler.WriteToken(token); return(Ok(new { accessToken })); }
public DerivedJwtSecurityToken(JwtHeader header, JwtPayload payload, string encodedJwt) : base(header, payload, encodedJwt) { Init(); }
public void JwtPayload_GetSets() { // Aud, Claims, ValidFrom, ValidTo handled in Defaults. JwtPayload jwtPayload = new JwtPayload(); Type type = typeof(JwtPayload); PropertyInfo[] properties = type.GetProperties(); if (properties.Length != 20) Assert.Fail("Number of properties has changed from 20 to: " + properties.Length + ", adjust tests"); GetSetContext context = new GetSetContext { PropertyNamesAndSetGetValue = new List<KeyValuePair<string, List<object>>> { new KeyValuePair<string, List<object>>("Actort", new List<object>{(string)null, Guid.NewGuid().ToString(), Guid.NewGuid().ToString()}), new KeyValuePair<string, List<object>>("Acr", new List<object>{(string)null, Guid.NewGuid().ToString(), Guid.NewGuid().ToString()}), new KeyValuePair<string, List<object>>("Amr", new List<object>{(string)null, Guid.NewGuid().ToString(), Guid.NewGuid().ToString()}), new KeyValuePair<string, List<object>>("AuthTime", new List<object>{(string)null, Guid.NewGuid().ToString(), Guid.NewGuid().ToString()}), new KeyValuePair<string, List<object>>("Azp", new List<object>{(string)null, Guid.NewGuid().ToString(), Guid.NewGuid().ToString()}), new KeyValuePair<string, List<object>>("CHash", new List<object>{(string)null, Guid.NewGuid().ToString(), Guid.NewGuid().ToString()}), new KeyValuePair<string, List<object>>("Exp", new List<object>{(string)null, 1, 0 }), new KeyValuePair<string, List<object>>("Jti", new List<object>{(string)null, Guid.NewGuid().ToString(), Guid.NewGuid().ToString()}), new KeyValuePair<string, List<object>>("Iat", new List<object>{(string)null, 10, 0}), new KeyValuePair<string, List<object>>("Iss", new List<object>{(string)null, Guid.NewGuid().ToString(), Guid.NewGuid().ToString()}), new KeyValuePair<string, List<object>>("Nbf", new List<object>{(string)null, 1, 0 }), new KeyValuePair<string, List<object>>("Nonce", new List<object>{(string)null, Guid.NewGuid().ToString(), Guid.NewGuid().ToString()}), new KeyValuePair<string, List<object>>("Sub", new List<object>{(string)null, Guid.NewGuid().ToString(), Guid.NewGuid().ToString()}), }, Object = jwtPayload, }; TestUtilities.GetSet(context); if (context.Errors.Count != 0) { StringBuilder sb = new StringBuilder(); sb.AppendLine(Environment.NewLine); foreach (string str in context.Errors) sb.AppendLine(str); Assert.Fail(sb.ToString()); } }
public void JwtPayload_GetSets() { // Aud, Claims, ValidFrom, ValidTo handled in Defaults. JwtPayload jwtPayload = new JwtPayload(); Type type = typeof(JwtPayload); PropertyInfo[] properties = type.GetProperties(); if (properties.Length != 20) { Assert.Fail("Number of properties has changed from 20 to: " + properties.Length + ", adjust tests"); } GetSetContext context = new GetSetContext { PropertyNamesAndSetGetValue = new List <KeyValuePair <string, List <object> > > { new KeyValuePair <string, List <object> >("Actort", new List <object> { (string)null, Guid.NewGuid().ToString(), Guid.NewGuid().ToString() }), new KeyValuePair <string, List <object> >("Acr", new List <object> { (string)null, Guid.NewGuid().ToString(), Guid.NewGuid().ToString() }), new KeyValuePair <string, List <object> >("Amr", new List <object> { (string)null, Guid.NewGuid().ToString(), Guid.NewGuid().ToString() }), new KeyValuePair <string, List <object> >("AuthTime", new List <object> { (string)null, Guid.NewGuid().ToString(), Guid.NewGuid().ToString() }), new KeyValuePair <string, List <object> >("Azp", new List <object> { (string)null, Guid.NewGuid().ToString(), Guid.NewGuid().ToString() }), new KeyValuePair <string, List <object> >("CHash", new List <object> { (string)null, Guid.NewGuid().ToString(), Guid.NewGuid().ToString() }), new KeyValuePair <string, List <object> >("Exp", new List <object> { (string)null, 1, 0 }), new KeyValuePair <string, List <object> >("Jti", new List <object> { (string)null, Guid.NewGuid().ToString(), Guid.NewGuid().ToString() }), new KeyValuePair <string, List <object> >("Iat", new List <object> { (string)null, 10, 0 }), new KeyValuePair <string, List <object> >("Iss", new List <object> { (string)null, Guid.NewGuid().ToString(), Guid.NewGuid().ToString() }), new KeyValuePair <string, List <object> >("Nbf", new List <object> { (string)null, 1, 0 }), new KeyValuePair <string, List <object> >("Nonce", new List <object> { (string)null, Guid.NewGuid().ToString(), Guid.NewGuid().ToString() }), new KeyValuePair <string, List <object> >("Sub", new List <object> { (string)null, Guid.NewGuid().ToString(), Guid.NewGuid().ToString() }), }, Object = jwtPayload, }; TestUtilities.GetSet(context); if (context.Errors.Count != 0) { StringBuilder sb = new StringBuilder(); sb.AppendLine(Environment.NewLine); foreach (string str in context.Errors) { sb.AppendLine(str); } Assert.Fail(sb.ToString()); } }
/// <summary> /// Generate token and then output if authenticated /// </summary> /// <param name="context">The Microsoft.AspNetCore.Http.HttpContext for the current request.</param> /// <returns></returns> private async Task WriteTokenAsync(HttpContext context) { _logger?.LogDebug("Attempting to get identity."); // Try to get identity (sign in) var identityResult = await _serviceProvider.GetRequiredService <IIdentityVerification>().GetIdentity(context); if (identityResult == null) { throw new ArgumentNullException(nameof(identityResult)); } else { if (identityResult.Identity == null) { _logger?.LogError("Verify identity failed."); context.Response.StatusCode = 400; context.Response.ContentType = "application/json"; await context.Response.WriteAsync(string.IsNullOrEmpty(identityResult.ErrorMessage)? "Invalid username or password." : identityResult.ErrorMessage); return; } } var now = DateTime.UtcNow; // Create clamins var claims = new List <Claim> { new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()) }; if (!string.IsNullOrEmpty(_options.Subject)) { claims.Add(new Claim(JwtRegisteredClaimNames.Sub, _options.Subject)); } claims.AddRange(identityResult.Identity.Claims); // Create the JWT and write it to a string _logger?.LogDebug("Attempting to generate jwt token."); // build signing credentials. var signingCredentials = new SigningCredentials(_options.SecurityKey, SecurityAlgorithms.HmacSha256); var jwtHeader = new JwtHeader(signingCredentials); var jwtPayload = new JwtPayload( issuer: _options.Issuer, audience: _options.Audience, claims: claims, notBefore: now, expires: now.Add(identityResult.Expiration), issuedAt: now); var jwt = new JwtSecurityToken(jwtHeader, jwtPayload); var encodedJwt = new JwtSecurityTokenHandler().WriteToken(jwt); _logger?.LogDebug($"Jwt token generated successful."); var response = new AccessToken { Scheme = _options.Scheme, Token = encodedJwt, ExpiresIn = (int)identityResult.Expiration.TotalSeconds }; // Serialize and return the response context.Response.ContentType = "application/json"; await context.Response.WriteAsync(JsonConvert.SerializeObject(response, Formatting.Indented, new JsonSerializerSettings { ContractResolver = new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver() })); }
private static JwsDescriptor CreateJws(Jwk signingKey, Dictionary <string, object> descriptor, TokenValidationStatus status, string claim = null) { var payload = new JwtPayload(); foreach (var kvp in descriptor) { switch (status) { case TokenValidationStatus.InvalidClaim: if (kvp.Key == "aud" && claim == "aud") { payload.Add(kvp.Key, kvp.Value + "XXX"); continue; } if (kvp.Key == "iss" && claim == "iss") { payload.Add(kvp.Key, kvp.Value + "XXX"); continue; } break; case TokenValidationStatus.MissingClaim: if (kvp.Key == "exp" & claim == "exp") { continue; } if (kvp.Key == "aud" & claim == "aud") { continue; } if (kvp.Key == "iss" && claim == "iss") { continue; } break; case TokenValidationStatus.Expired: if (kvp.Key == "exp") { payload.Add(kvp.Key, 1500000000); continue; } if (kvp.Key == "nbf") { payload.Add(kvp.Key, 1400000000); continue; } break; case TokenValidationStatus.NotYetValid: if (kvp.Key == "exp") { payload.Add(kvp.Key, 2100000000); continue; } if (kvp.Key == "nbf") { payload.Add(kvp.Key, 2000000000); continue; } break; } payload.Add(kvp.Key, kvp.Value); } var d = new JwsDescriptor(signingKey, signingKey.SignatureAlgorithm); d.Payload = payload; return(d); }
public string Create(IIdentity identity, string audience, List <string> appGroupRegexes) { var nowUtc = DateTime.UtcNow; var expires = _settings.TokenExpiryMinutes > 0 ? nowUtc.AddMinutes(_settings.TokenExpiryMinutes) : nowUtc.AddDays(_settings.TokenExpiryDays); var centuryBegin = new DateTime(1970, 1, 1); var exp = (long)(new TimeSpan(expires.Ticks - centuryBegin.Ticks).TotalSeconds); var now = (long)(new TimeSpan(nowUtc.Ticks - centuryBegin.Ticks).TotalSeconds); var issuer = _settings.Issuer ?? string.Empty; var payload = new JwtPayload { { "sub", identity.Name }, { "unique_name", identity.Name }, { "iss", issuer }, { "aud", audience }, { "iat", now }, { "nbf", now }, { "exp", exp }, { "jti", Guid.NewGuid().ToString("N") } }; var windowsUser = identity as WindowsIdentity; // SId var claim = windowsUser.Claims.FirstOrDefault(c => c.Type == ClaimTypes.PrimarySid); if (claim != null) { payload.AddClaim(new Claim("sid", claim.Value)); } // Group SId if (_settings.IncludeGroupSIdClaims) { var groupClaims = windowsUser.Claims.Where(c => c.Type == ClaimTypes.GroupSid); if (groupClaims != null) { foreach (Claim c in groupClaims) { payload.AddClaim(new Claim(c.Type, c.Value)); } } } // Group Roles if (_settings.IncludeGroupRoleClaims) { var groupClaims = windowsUser.Claims.Where(c => c.Type == ClaimTypes.GroupSid); if (groupClaims != null) { foreach (Claim c in groupClaims) { var role = new System.Security.Principal.SecurityIdentifier(c.Value).Translate(typeof(System.Security.Principal.NTAccount)).ToString(); foreach (var regex in appGroupRegexes) { if (Regex.IsMatch(role, regex)) { payload.AddClaim(new Claim("role", role)); } } } } } var jwt = new JwtSecurityToken(_jwtHeader, payload); return(_jwtSecurityTokenHandler.WriteToken(jwt)); }
static void Main(string[] args) { // Read the file to string var configFileName = "../config.json"; var reader = new StreamReader(configFileName); var json = reader.ReadToEnd(); // Use the powerful Newtonsoft.Json library // (https://www.newtonsoft.com/json) // to covert the string into a Config object var config = JsonConvert.DeserializeObject <Config>(json); // We use BouncyCastle (BouncyCastle.NetCore) to handle // the decryption // (https://www.bouncycastle.org/csharp/index.html) // Next, we use BouncyCastle's PemReader to read the // decrypt the private key into a RsaPrivateCrtKeyParameters // object var appAuth = config.boxAppSettings.appAuth; var stringReader = new StringReader(appAuth.privateKey); var passwordFinder = new PasswordFinder(appAuth.passphrase); var pemReader = new PemReader(stringReader, passwordFinder); var keyParams = (RsaPrivateCrtKeyParameters)pemReader.ReadObject(); // In the end, we will use this key in the next steps var key = CreateRSAProvider(ToRSAParameters(keyParams)); // We create a random identifier that helps protect against // replay attacks byte[] randomNumber = new byte[64]; RandomNumberGenerator.Create().GetBytes(randomNumber); var jti = Convert.ToBase64String(randomNumber); // We give the assertion a lifetime of 45 seconds // before it expires DateTime expirationTime = DateTime.UtcNow.AddSeconds(45); // Next, we are read to assemble the payload var claims = new List <Claim> { new Claim("sub", config.enterpriseID), new Claim("box_sub_type", "enterprise"), new Claim("jti", jti), }; String authenticationUrl = "https://api.box.com/oauth2/token"; // Rather than constructing the JWT assertion manually, we are // using the System.IdentityModel.Tokens.Jwt library. var payload = new JwtPayload( config.boxAppSettings.clientID, authenticationUrl, claims, null, expirationTime ); // The API support "RS256", "RS384", and "RS512" encryption var credentials = new SigningCredentials( new RsaSecurityKey(key), SecurityAlgorithms.RsaSha512 ); var header = new JwtHeader(signingCredentials: credentials); // Finally, let's create the assertion usign the // header and payload var jst = new JwtSecurityToken(header, payload); var tokenHandler = new JwtSecurityTokenHandler(); string assertion = tokenHandler.WriteToken(jst); // We start by preparing the params to send to // the authentication endpoint var content = new FormUrlEncodedContent(new[] { // This specifies that we are using a JWT assertion // to authenticate new KeyValuePair <string, string>( "grant_type", "urn:ietf:params:oauth:grant-type:jwt-bearer"), // Our JWT assertion new KeyValuePair <string, string>( "assertion", assertion), // The OAuth 2 client ID and secret new KeyValuePair <string, string>( "client_id", config.boxAppSettings.clientID), new KeyValuePair <string, string>( "client_secret", config.boxAppSettings.clientSecret) }); // Make the POST call to the authentication endpoint var client = new HttpClient(); var response = client.PostAsync(authenticationUrl, content).Result; var data = response.Content.ReadAsStringAsync().Result; var token = JsonConvert.DeserializeObject <Token>(data); var accessToken = token.access_token; // Folder 0 is the root folder for this account // and should be empty by default String url = "https://api.box.com/2.0/folders/0"; client = new HttpClient(); client.DefaultRequestHeaders.Add( "Authorization", "Bearer " + accessToken ); response = client.GetAsync(url).Result; data = response.Content.ReadAsStringAsync().Result; Console.WriteLine(data); }
public async Task <IActionResult> SignInBindCallBack(string provider, string redirectUrl = "", string token = "") { if (string.IsNullOrWhiteSpace(provider)) { return(BadRequest()); } if (!await HttpContext.IsProviderSupportedAsync(provider)) { return(BadRequest()); } if (token.IsNullOrEmpty() || !token.StartsWith("Bearer ")) { return(Redirect($"{redirectUrl}#bind-result?code={ErrorCode.Fail}&message={HttpUtility.UrlEncode("请先登录")}")); } else { token = token.Remove(0, 7); } AuthenticateResult authenticateResult = await _contextAccessor.HttpContext.AuthenticateAsync(provider); if (!authenticateResult.Succeeded) { return(Redirect($"{redirectUrl}#bind-result?code=fail&message={authenticateResult.Failure.Message}")); } var openIdClaim = authenticateResult.Principal.FindFirst(ClaimTypes.NameIdentifier); if (openIdClaim == null || string.IsNullOrWhiteSpace(openIdClaim.Value)) { return(Redirect($"{redirectUrl}#bind-result?code={ErrorCode.Fail}&message={HttpUtility.UrlEncode("未能获取openId")}")); } JwtPayload jwtPayload = (JwtPayload)_jsonWebTokenService.Decode(token); string nameIdentifier = jwtPayload.Claims.FirstOrDefault(r => r.Type == ClaimTypes.NameIdentifier)?.Value; if (nameIdentifier.IsNullOrWhiteSpace()) { return(Redirect($"{redirectUrl}#bind-result?code={ErrorCode.Fail}&message={HttpUtility.UrlEncode("请先登录")}")); } long userId = long.Parse(nameIdentifier); UnifyResponseDto unifyResponseDto; List <string> supportProviders = new List <string> { LinUserIdentity.Gitee, LinUserIdentity.GitHub, LinUserIdentity.QQ }; if (!supportProviders.Contains(provider)) { _logger.LogError($"未知的privoder:{provider},redirectUrl:{redirectUrl}"); unifyResponseDto = UnifyResponseDto.Error($"未知的privoder:{provider}!"); } else { IOAuth2Service oAuth2Service = _componentContext.ResolveNamed <IOAuth2Service>(provider); unifyResponseDto = await oAuth2Service.BindAsync(authenticateResult.Principal, provider, openIdClaim.Value, userId); } return(Redirect($"{redirectUrl}#bind-result?code={unifyResponseDto.Code.ToString()}&message={HttpUtility.UrlEncode(unifyResponseDto.Message.ToString())}")); }
public static AccessToken CreateAccessToken(string token) { JwtPayload payload = DecodeJwtPayload(token); return(new AccessToken(token, payload.ExpiresOn)); }
public bool Validate(JwtPayload payload) { return(payload.Validate <string>(JTokenType.String, "userId", (id) => true)); }
protected override void ProcessRecord() { base.ProcessRecord(); IAuthContext authConfig = new AuthContext { TenantId = TenantId }; CancellationToken cancellationToken = CancellationToken.None; if (ParameterSetName == Constants.UserParameterSet) { // 2 mins timeout. 1 min < HTTP timeout. TimeSpan authTimeout = new TimeSpan(0, 0, Constants.MaxDeviceCodeTimeOut); CancellationTokenSource cts = new CancellationTokenSource(authTimeout); cancellationToken = cts.Token; authConfig.AuthType = AuthenticationType.Delegated; authConfig.Scopes = Scopes ?? new string[] { "User.Read" }; } else { authConfig.AuthType = AuthenticationType.AppOnly; authConfig.ClientId = ClientId; authConfig.CertificateThumbprint = CertificateThumbprint; authConfig.CertificateName = CertificateName; } try { // Gets a static instance of IAuthenticationProvider when the client app hasn't changed. IAuthenticationProvider authProvider = AuthenticationHelpers.GetAuthProvider(authConfig); IClientApplicationBase clientApplication = null; if (ParameterSetName == Constants.UserParameterSet) { clientApplication = (authProvider as DeviceCodeProvider).ClientApplication; } else { clientApplication = (authProvider as ClientCredentialProvider).ClientApplication; } // Incremental scope consent without re-instanciating the auth provider. We will use a static instance. GraphRequestContext graphRequestContext = new GraphRequestContext(); graphRequestContext.CancellationToken = cancellationToken; graphRequestContext.MiddlewareOptions = new Dictionary <string, IMiddlewareOption> { { typeof(AuthenticationHandlerOption).ToString(), new AuthenticationHandlerOption { AuthenticationProviderOption = new AuthenticationProviderOption { Scopes = authConfig.Scopes, ForceRefresh = ForceRefresh } } } }; // Trigger consent. HttpRequestMessage httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, "https://graph.microsoft.com/v1.0/me"); httpRequestMessage.Properties.Add(typeof(GraphRequestContext).ToString(), graphRequestContext); authProvider.AuthenticateRequestAsync(httpRequestMessage).GetAwaiter().GetResult(); var accounts = clientApplication.GetAccountsAsync().GetAwaiter().GetResult(); var account = accounts.FirstOrDefault(); JwtPayload jwtPayload = JwtHelpers.DecodeToObject <JwtPayload>(httpRequestMessage.Headers.Authorization?.Parameter); authConfig.Scopes = jwtPayload?.Scp?.Split(' ') ?? jwtPayload?.Roles; authConfig.TenantId = jwtPayload?.Tid ?? account?.HomeAccountId?.TenantId; authConfig.AppName = jwtPayload?.AppDisplayname; authConfig.Account = jwtPayload?.Upn ?? account?.Username; // Save auth config to session state. GraphSession.Instance.AuthContext = authConfig; } catch (AuthenticationException authEx) { if ((authEx.InnerException is TaskCanceledException) && cancellationToken.IsCancellationRequested) { throw new Exception($"Device code terminal timed-out after {Constants.MaxDeviceCodeTimeOut} seconds. Please try again."); } else { throw authEx.InnerException ?? authEx; } } catch (Exception ex) { throw ex.InnerException ?? ex; } WriteObject("Welcome To Microsoft Graph!"); }
public void CreateAndValidateTokens_JsonClaims() { List<string> errors = new List<string>(); string issuer = "http://www.GotJWT.com"; string claimSources = "_claim_sources"; string claimNames = "_claim_names"; JwtPayload jwtPayloadClaimSources = new JwtPayload(); jwtPayloadClaimSources.Add(claimSources, JsonClaims.ClaimSources); jwtPayloadClaimSources.Add(claimNames, JsonClaims.ClaimNames); JwtSecurityToken jwtClaimSources = new JwtSecurityToken( new JwtHeader(), jwtPayloadClaimSources); JwtSecurityTokenHandler jwtHandler = new JwtSecurityTokenHandler(); string encodedJwt = jwtHandler.WriteToken(jwtClaimSources); var validationParameters = new TokenValidationParameters { IssuerValidator = (s, st, tvp) => { return issuer;}, RequireSignedTokens = false, ValidateAudience = false, ValidateLifetime = false, }; SecurityToken validatedJwt = null; var claimsPrincipal = jwtHandler.ValidateToken(encodedJwt, validationParameters, out validatedJwt); if (!IdentityComparer.AreEqual (claimsPrincipal.Identity as ClaimsIdentity, JsonClaims.ClaimsIdentityDistributedClaims(issuer, TokenValidationParameters.DefaultAuthenticationType, JsonClaims.ClaimSources, JsonClaims.ClaimNames))) { errors.Add("JsonClaims.ClaimSources, JsonClaims.ClaimNames: test failed"); }; Claim c = claimsPrincipal.FindFirst(claimSources); if (!c.Properties.ContainsKey(JwtSecurityTokenHandler.JsonClaimTypeProperty)) { errors.Add(claimSources + " claim, did not have json property: " + JwtSecurityTokenHandler.JsonClaimTypeProperty); } else { if (!string.Equals(c.Properties[JwtSecurityTokenHandler.JsonClaimTypeProperty], typeof(IDictionary<string, object>).ToString(), StringComparison.Ordinal)) { errors.Add("!string.Equals(c.Properties[JwtSecurityTokenHandler.JsonClaimTypeProperty], typeof(IDictionary<string, object>).ToString(), StringComparison.Ordinal)" + "value is: " + c.Properties[JwtSecurityTokenHandler.JsonClaimTypeProperty]); } } JwtSecurityToken jwtWithEntity = new JwtSecurityToken( new JwtHeader(), new JwtPayload(claims: ClaimSets.EntityAsJsonClaim(issuer, issuer))); encodedJwt = jwtHandler.WriteToken(jwtWithEntity); JwtSecurityToken jwtRead = jwtHandler.ReadToken(encodedJwt) as JwtSecurityToken; SecurityToken validatedToken; var cp = jwtHandler.ValidateToken(jwtRead.RawData, validationParameters, out validatedToken); Claim jsonClaim = cp.FindFirst(typeof(Entity).ToString()); if (jsonClaim == null) { errors.Add("Did not find Jsonclaims. Looking for claim of type: '" + typeof(Entity).ToString() + "'"); }; string jsString = JsonExtensions.SerializeToJson(Entity.Default); if (!string.Equals(jsString, jsonClaim.Value, StringComparison.Ordinal)) { errors.Add(string.Format(CultureInfo.InvariantCulture, "Find Jsonclaims of type: '{0}', but they weren't equal.\nExpecting:\n'{1}'.\nReceived:\n'{2}'", typeof(Entity).ToString(), jsString, jsonClaim.Value)); } TestUtilities.AssertFailIfErrors(MethodInfo.GetCurrentMethod().Name, errors); }
/*private string GetSignedJwtToken(string rsaKeyFilePath, X509Certificate2 cert, string url) { //var claimsetSerialized = @"{""token_class"":""solution_assertion"",""token_type"":""Bearer""" + // @",""jti"":""" + new Random().Next().ToString() + @"""" + // @",""iss"":""" + cert.Subject + @""",""sub"":""" + cert.Subject + @"""" + // @",""aud"":""" + url + @""",""iat"":""" + DateTimeHelper.WindowsToUnix(DateTime.Now).ToString() + @"""" + // @",""exp"":""" + DateTimeHelper.WindowsToUnix(DateTime.Now.AddTicks(356 * 24 * 60 * 60)).ToString() + @"""}"; // header //var headerSerialized = @"{""typ"":""JWT"", ""alg"":""RS256""}"; var header = new JwtHeaderDto { Typ = "JWT", Alg = "RS256" }; // encoded header var headerSerialized = JsonConvert.Serialize(header); var headerBytes = Encoding.UTF8.GetBytes(headerSerialized); var headerEncoded = Convert.ToBase64String(headerBytes); // encoded claimset var claimset = new JwtClaimDto { TokenClass = "solution_assertion", TokenType = "Bearer", Jti = new Random().Next().ToString(), Iss = cert.Subject, Sub = cert.Subject, Aud = url, Iat = DateTimeHelper.WindowsToUnix(DateTime.Now).ToString(), Exp = DateTimeHelper.WindowsToUnix(DateTime.Now.AddTicks(356 * 24 * 60 * 60)).ToString() }; //var claimset = new JwtPayload //{ // Jti = new Random().Next().ToString(), // Iss = cert.Subject, // Sub = cert.Subject, // Aud = url, // Iat = DateTimeHelper.WindowsToUnix(DateTime.Now).ToString(), // Exp = DateTimeHelper.WindowsToUnix(DateTime.Now.AddTicks(356 * 24 * 60 * 60)).ToString(), // Claims = new List<Claim>() { new Claim("token_class", "solution_assertion"), new Claim("token_type", "Bearer") } //}; //var claimset = new JwtPayload(); //var claims = new List<Claim>(); //claims.Add(new Claim("token_class", "solution_assertion")); //claims.Add(new Claim("token_type", "Bearer")); //claims.Add(new Claim("jti", new Random().Next().ToString())); //claims.Add(new Claim("iss", cert.Subject)); //claims.Add(new Claim("sub", cert.Subject)); //claims.Add(new Claim("aud", url)); //claims.Add(new Claim("iat", DateTimeHelper.WindowsToUnix(DateTime.Now).ToString())); //claims.Add(new Claim("exp", DateTimeHelper.WindowsToUnix(DateTime.Now.AddTicks(356 * 24 * 60 * 60)).ToString())); //claimset.AddClaims(claims); var claimsetSerialized = JsonConvert.Serialize(claimset); var claimsetBytes = Encoding.UTF8.GetBytes(claimsetSerialized); var claimsetEncoded = Convert.ToBase64String(claimsetBytes); // input var input = String.Join(".", headerEncoded, claimsetEncoded); var inputBytes = Encoding.UTF8.GetBytes(input); //var signatureBytes = rsaKey.SignData(inputBytes, "SHA256"); var signature = ShaWithRsaSigner.Sign(input, rsaKeyFilePath, "SHA256"); var signatureBytes = Encoding.UTF8.GetBytes(signature); var signatureEncoded = Convert.ToBase64String(signatureBytes); // jwt return String.Join(".", input, signatureEncoded); }*/ private string GetSignedJwtToken(RSACryptoServiceProvider rsa, X509Certificate2 cert, string url) { var claims = new List<Claim>(); claims.Add(new Claim("token_class", "solution_assertion")); claims.Add(new Claim("token_type", "Bearer")); claims.Add(new Claim("jti", new Random().Next().ToString())); claims.Add(new Claim("sub", cert.Subject)); var payload = new JwtPayload(cert.Issuer, url, claims, DateTime.Now, DateTime.Now.AddMinutes(5)); //var cert = new X509Certificate2(Encoding.UTF8.GetBytes(certificate.Encoded)); //var signingCredentials = new X509SigningCredentials(cert); //var payload = new JwtPayload(cert.Subject,url, DateTime.Now,DateTime.Now.AddMinutes(5)); //var claims = new List<Claim>(); //claims.Add(new Claim("token_class", "solution_assertion")); //claims.Add(new Claim("token_type", "Bearer")); //claims.Add(new Claim("jti", new Random().Next().ToString())); //claims.Add(new Claim("iss", cert.Subject)); //claims.Add(new Claim("sub", cert.Subject)); //claims.Add(new Claim("aud", url)); //claims.Add(new Claim("iat", DateTimeHelper.WindowsToUnix(DateTime.Now).ToString())); //claims.Add(new Claim("exp", DateTimeHelper.WindowsToUnix(DateTime.Now.AddTicks(356 * 24 * 60 * 60)).ToString())); //payload.Exp = DateTimeHelper.WindowsToUnix(DateTime.Now.AddTicks(356 * 24 * 60 * 60)); //payload.Iat = DateTimeHelper.WindowsToUnix(DateTime.Now); //payload.AddClaims(claims); //var keyBytes = GetBytes(privateKey.Encoded); //var key = new InMemorySymmetricSecurityKey(keyBytes); var key = new RsaSecurityKey(rsa); var signingCredentials = new SigningCredentials(key, SecurityAlgorithms.RsaSha256Signature, SecurityAlgorithms.Sha256Digest); var header = new JwtHeader(signingCredentials); var token = new JwtSecurityToken(header, payload); var jwtSecurityTokenHandler = new JwtSecurityTokenHandler(); try { var jsonToken = jwtSecurityTokenHandler.WriteToken(token); return jsonToken; } catch (Exception) { // todo: Log exception } return null; }
// Fixes linker miss, per https://github.com/mono/linker/issues/870 static JwtClaimsTokenHandler() { _ = new JwtHeader(); _ = new JwtPayload(); }
/// <summary> /// Helper class to retreive more easily all claims used by Apple in the <see cref="JwtPayload"/> /// </summary> public static AppleJwtTokenPayload ToAppleJwtPayload(this JwtPayload jwtPayload) => new AppleJwtTokenPayload(jwtPayload.Claims);
public HttpResponseMessage GenerateOwtToken([FromBody] OwtPayloadContract owtPayloadContract) { HttpResponseMessage resMsg = null; // Log the Request Contract Payload Helper.LogData(ConfigurationManager.AppSettings["ServiceLog"], $"[{Helper.ServerIP(Request.Headers.Host)}] [GenerateWebToken:{owtPayloadContract}]"); try { // Need to Create the Signing Credentials With the Encrypted Public Key. var securityKey = File.ReadAllText(ConfigurationManager.AppSettings["EncryptedPublicKey"]) .Replace("-----BEGIN PUBLIC KEY-----\n", "") .Replace("\n-----END PUBLIC KEY-----\n", ""); var signingKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(securityKey)); var signingCredentials = new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256Signature); var header = new JwtHeader(signingCredentials); var payload = new JwtPayload( // Issuer - String owtPayloadContract.Issuer, // Audience - String owtPayloadContract.Audience, // Claims - IEnumerable<Claims> new List <Claim>() { new Claim(ClaimTypes.Uri, owtPayloadContract.URI), new Claim(ClaimTypes.Actor, owtPayloadContract.Actor), new Claim(ClaimTypes.Role, owtPayloadContract.Role), new Claim(ClaimTypes.Sid, owtPayloadContract.SID), new Claim(ClaimTypes.Name, owtPayloadContract.Name), new Claim(ClaimTypes.NameIdentifier, owtPayloadContract.EmployeeId), new Claim(ClaimTypes.Dns, owtPayloadContract.DNS), new Claim(ClaimTypes.Email, owtPayloadContract.Email), new Claim(ClaimTypes.Hash, owtPayloadContract.MacAddress), new Claim(ClaimTypes.Locality, owtPayloadContract.IpAddress) }, // Not Before - DateTime? owtPayloadContract.NotBefore, // Expires - DateTime? owtPayloadContract.Expires, // Issued At - DateTime? owtPayloadContract.IssuedAt ); // End of JwtPayLoad Paramaters var secToken = new JwtSecurityToken(header, payload); var handler = new JwtSecurityTokenHandler(); var tokenString = handler.WriteToken(secToken); // Log the token that was generated. Helper.LogData(ConfigurationManager.AppSettings["ServiceLog"], $"[{Helper.ServerIP(Request.Headers.Host)}] [JSON_WEB_TOKEN:{(!string.IsNullOrEmpty(tokenString) ? "CREATED" : "NULL|EMPTY")}]"); resMsg = Request.CreateResponse(HttpStatusCode.OK, tokenString); } catch (Exception ex) { Helper.LogData(ConfigurationManager.AppSettings["ExceptionLog"], $"[{Helper.ServerIP(Request.Headers.Host)}] [GenerateJwtToken: {ex.Message}]"); resMsg = Request.CreateResponse(HttpStatusCode.NotAcceptable, ex); } return(resMsg); }
public IActionResult VerifyToken([FromHeader(Name = HEADER_AUTH)] string token) { IActionResult response = Unauthorized(); var headerKeys = string.Empty; foreach (var key in Request.Headers.Keys) { headerKeys += key.ToString() + ", "; } headerKeys = headerKeys.Substring(0, headerKeys.Length - 2); if (Request.Headers.Keys.Contains(HEADER_AUTH)) { var reqHeader = Request.Headers.FirstOrDefault(h => h.Key == HEADER_AUTH); if (reqHeader.Value != string.Empty && reqHeader.Value != "null") { try { if (ModelState.IsValid) // ModelState อาจจะไม่จำเป็นต้องใช้ หรือใช้ไม่ได้กับ API { try { var handler = new JwtSecurityTokenHandler(); var jwtSecToken = handler.ReadToken(token) as JwtSecurityToken; string[] jwtArray = token.Split('.'); var jwtHeader = JwtHeader.Base64UrlDeserialize(jwtArray[0]); var jwtPayload = JwtPayload.Base64UrlDeserialize(jwtArray[1]); Jwt.Algorithm jwtAlg; if (jwtHeader.Alg == "HS256") { jwtAlg = Jwt.Algorithm.HS256; } else if (jwtHeader.Alg == "RS256") { jwtAlg = Jwt.Algorithm.RS256; } else if (jwtHeader.Alg == "ES256") { jwtAlg = Jwt.Algorithm.ES256; } else { jwtAlg = Jwt.Algorithm.HS256; } var tokenHandler = new JwtSecurityTokenHandler(); try { var claimPrincipal = tokenHandler.ValidateToken(token, new TokenValidationParameters { ValidIssuer = _config["Jwt:Issuer"], ValidAudience = _config["Jwt:Audience"], ValidateIssuer = true, ValidateAudience = true, ValidateLifetime = true, ValidateIssuerSigningKey = true, ClockSkew = TimeSpan.Zero, IssuerSigningKey = Jwt.GetSecurityKey(jwtAlg, _config, _azObj) }, out var parsedToken); var isAuthen = claimPrincipal.Identity.IsAuthenticated; if (isAuthen) { var result = "valid"; return(Ok(new { result, token })); } else { response = CustomHttpResponse.Error(HttpStatusCode.Unauthorized, Errors.Invalid_AccessToken, "Unauthorized, AccessToken (" + token + ") is invalid (Can Not Authenticated)."); } } catch (Exception ex) { response = CustomHttpResponse.Error(HttpStatusCode.Unauthorized, Errors.Invalid_AccessToken, "Unauthorized, AccessToken (" + token + ") is invalid (>> " + ex.Message + ")."); } } catch (Exception ex) { response = CustomHttpResponse.Error(HttpStatusCode.Unauthorized, Errors.Invalid_AccessToken, "Unauthorized, AccessToken (" + token + ") is invalid (> " + ex.Message + ")."); } } else // ModelState อาจจะไม่จำเป็นต้องใช้ หรือใช้ไม่ได้กับ API { response = CustomHttpResponse.Error(HttpStatusCode.Unauthorized, Errors.ExceptionalOccured, "Unauthorized, Input Model ('" + headerKeys + "') is invalid."); } } catch (Exception ex) { response = CustomHttpResponse.Error(HttpStatusCode.Unauthorized, Errors.ExceptionalOccured, "Unauthorized, Exception occurred (" + ex.Message + " - " + ex.Source + " - " + ex.StackTrace + " - " + ex.InnerException + " - " + ex.HelpLink + ")."); } } else { response = CustomHttpResponse.Error(HttpStatusCode.Unauthorized, Errors.Invalid_AccessToken, "Unauthorized, AccessToken is empty"); } } else { response = CustomHttpResponse.Error(HttpStatusCode.Unauthorized, Errors.ExceptionalOccured, "Unauthorized, Input Model is invalid (There is no Auth-Jwt)."); } return(response); }
/// <inheritdoc /> /// <summary> /// Create a request with the claims in payload. /// </summary> /// <param name="payload"></param> public LtiDeepLinkingRequest(JwtPayload payload) : base(payload.Claims) { }
private string ConstructJWTAssertion(string sub, string boxSubType) { byte[] randomNumber = new byte[64]; using (var rng = new RNGCryptoServiceProvider()) { rng.GetBytes(randomNumber); } var claims = new List<Claim>{ new Claim("sub", sub), new Claim("box_sub_type", boxSubType), new Claim("jti", Convert.ToBase64String(randomNumber)), }; var payload = new JwtPayload(this.boxConfig.ClientId, AUTH_URL, claims, null, DateTime.UtcNow.AddSeconds(30)); var header = new JwtHeader(signingCredentials: this.credentials); if (this.boxConfig.JWTPublicKeyId != null) header.Add("kid", this.boxConfig.JWTPublicKeyId); var token = new JwtSecurityToken(header, payload); var tokenHandler = new JwtSecurityTokenHandler(); string assertion = tokenHandler.WriteToken(token); return assertion; }
/// <summary> /// Creates a base64-encoded JSON Web Token from a payload model. /// </summary> /// <param name="payload"></param> /// <returns>base64-encoded JWT</returns> public string Encode(JwtPayload payload) { var jwt = new JsonWebToken <JwtPayload>(payload, Signature()); return(jwt.ToEncodedString()); }
public static async Task <IEnumerable <Claim> > getList(string method, Dictionary <string, string> parameters = null) { #region generate token to send it to api byte[] key = Convert.FromBase64String(Secret); SymmetricSecurityKey securityKey = new SymmetricSecurityKey(key); var credentials = new Microsoft.IdentityModel.Tokens.SigningCredentials (securityKey, SecurityAlgorithms.HmacSha256Signature); // Finally create a Token var header = new JwtHeader(credentials); var nbf = DateTime.UtcNow.AddSeconds(-1); var exp = DateTime.UtcNow.AddSeconds(120); var payload = new JwtPayload(null, "", new List <Claim>(), nbf, exp); if (parameters != null) { for (int i = 0; i < parameters.Count; i++) { payload.Add(parameters.Keys.ToList()[i], parameters.Values.ToList()[i]); } } // add userLogInID to parameters payload.Add("userLogInID", MainWindow.userLogInID); var token = new JwtSecurityToken(header, payload); var handler = new JwtSecurityTokenHandler(); // Token to String so you can use post it to api string getToken = handler.WriteToken(token); var encryptedToken = EncryptThenCompress(getToken); //encryptedToken = HttpUtility.UrlPathEncode(encryptedToken); string tmpPath = writeToTmpFile(encryptedToken); //string dir = Directory.GetParent(Directory.GetCurrentDirectory()).Parent.FullName; //string tmpPath = Path.Combine(dir, Global.TMPFolder); // tmpPath = Path.Combine(tmpPath, "tmp.txt"); FileStream fs = new FileStream(tmpPath, FileMode.Open, FileAccess.Read); #endregion ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, sslPolicyErrors) => true; ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12; using (var client = new HttpClient()) { client.BaseAddress = new Uri(Global.APIUri); client.Timeout = System.TimeSpan.FromSeconds(3600); string boundary = string.Format("----WebKitFormBoundary{0}", DateTime.Now.Ticks.ToString("x")); MultipartFormDataContent form = new MultipartFormDataContent(); HttpContent content = new StreamContent(fs); content.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data") { FileName = "tmp.txt" }; content.Headers.Add("client", "true"); form.Add(content, "fileToUpload"); var response = await client.PostAsync(@method + "?token=" + "null", form); if (response.IsSuccessStatusCode) { var jsonString = await response.Content.ReadAsStringAsync(); var Sresponse = JsonConvert.DeserializeObject <string>(jsonString); fs.Dispose(); File.Delete(tmpPath); if (Sresponse != "") { var decryptedToken = DeCompressThenDecrypt(Sresponse); var jwtToken = new JwtSecurityToken(decryptedToken); var s = jwtToken.Claims.ToArray(); IEnumerable <Claim> claims = jwtToken.Claims; string validAuth = claims.Where(f => f.Type == "scopes").Select(x => x.Value).FirstOrDefault(); if (validAuth != null && s[2].Value == "-7") // invalid authintication { return(null); } else if (validAuth != null && s[2].Value == "-8") { MainWindow.go_out = true; } return(claims); } } else { fs.Dispose(); File.Delete(tmpPath); } } return(null); }
private static void SetDataSet(List <Claim> claims, TheoryData <List <Claim>, JwtPayload, JwtPayload> dataset) { var payloadDirect = new JwtPayload(); var jobj = new JObject(); foreach (var claim in claims) { object jsonValue = null; object existingValue; switch (claim.ValueType) { case ClaimValueTypes.String: jsonValue = claim.Value; break; case ClaimValueTypes.Boolean: jsonValue = bool.Parse(claim.Value); break; case ClaimValueTypes.Double: jsonValue = double.Parse(claim.Value, CultureInfo.InvariantCulture); break; case ClaimValueTypes.Integer: case ClaimValueTypes.Integer32: jsonValue = int.Parse(claim.Value, CultureInfo.InvariantCulture); break; case ClaimValueTypes.Integer64: jsonValue = long.Parse(claim.Value, CultureInfo.InvariantCulture); break; case ClaimValueTypes.DateTime: jsonValue = DateTime.Parse(claim.Value); break; case JsonClaimValueTypes.Json: jsonValue = JObject.Parse(claim.Value); break; case JsonClaimValueTypes.JsonArray: jsonValue = JArray.Parse(claim.Value); break; } JToken jtoken = null; if (jobj.TryGetValue(claim.Type, out jtoken)) { JArray jarray = jtoken as JArray; if (jarray == null) { jarray = new JArray(); jarray.Add(jtoken); jobj.Remove(claim.Type); jobj.Add(claim.Type, jarray); } jarray.Add(JToken.FromObject(jsonValue)); } else { jobj.Add(claim.Type, JToken.FromObject(jsonValue)); } if (payloadDirect.TryGetValue(claim.Type, out existingValue)) { IList <object> claimValues = existingValue as IList <object>; if (claimValues == null) { claimValues = new List <object>(); claimValues.Add(existingValue); payloadDirect[claim.Type] = claimValues; } claimValues.Add(jsonValue); } else { payloadDirect[claim.Type] = jsonValue; } } var j = jobj.ToString(Formatting.None); var payloadDeserialized = JwtPayload.Deserialize(j); dataset.Add(claims, payloadDirect, payloadDeserialized); }
public void JwtPayload_Mono_ClaimArrayDecomposition() { List<string> errors = new List<string>(); var jwtPayload = new JwtPayload(); jwtPayload["scope"] = new ArrayList() { "openid", "email", "profile" }; int claimCount = ((IList<Claim>)jwtPayload.Claims).Count; if (claimCount != 3) { errors.Add("!claimCount == 3"); } TestUtilities.AssertFailIfErrors(MethodInfo.GetCurrentMethod().Name, errors); }
private async Task GenerateToken(HttpContext context) { _logger?.LogDebug("Attempting to get identity."); // Try to get identity (sign in) var identity = await _userFinder.GetIdentity(context); if (identity == null) { _logger?.LogError("Invalid username or password."); context.Response.StatusCode = 500; context.Response.ContentType = "application/json"; await context.Response.WriteAsync(JsonConvert.SerializeObject( new ApiErrorResult { Type = ErrorType.SignInFailed, Message = "Invalid username or password." }, Formatting.Indented, new JsonSerializerSettings { ContractResolver = new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver() })); return; } var now = DateTime.UtcNow; // Create clamins var claims = new List <Claim> { new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()) }; if (!string.IsNullOrEmpty(_options.Subject)) { claims.Add(new Claim(JwtRegisteredClaimNames.Sub, _options.Subject)); } claims.AddRange(identity.Claims); // Create the JWT and write it to a string _logger?.LogDebug("Attempting to generate jwt token."); var jwtHeader = new JwtHeader(_options.SigningCredentials); var jwtPayload = new JwtPayload( issuer: _options.Issuer, audience: _options.Audience, claims: claims, notBefore: now, expires: now.Add(_options.Expiration), issuedAt: now); var jwt = new JwtSecurityToken(jwtHeader, jwtPayload); var encodedJwt = new JwtSecurityTokenHandler().WriteToken(jwt); _logger?.LogDebug($"Jwt token generated successful."); var response = new AccessToken { scheme = "Bearer", access_token = encodedJwt, expires_in = (int)_options.Expiration.TotalSeconds }; // Serialize and return the response context.Response.ContentType = "application/json"; await context.Response.WriteAsync(JsonConvert.SerializeObject(response, Formatting.Indented, new JsonSerializerSettings { ContractResolver = new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver() })); }
/// <summary> /// Initializes a new instance of the <see cref="JwtSecurityToken"/> class where the <see cref="JwtHeader"/> contains the crypto algorithms applied to the encoded <see cref="JwtHeader"/> and <see cref="JwtPayload"/>. The jwtEncodedString is the result of those operations. /// </summary> /// <param name="header">Contains JSON objects representing the cryptographic operations applied to the JWT and optionally any additional properties of the JWT</param> /// <param name="payload">Contains JSON objects representing the claims contained in the JWT. Each claim is a JSON object of the form { Name, Value }</param> /// <exception cref="ArgumentNullException">'header' is null.</exception> /// <exception cref="ArgumentNullException">'payload' is null.</exception> public JwtSecurityToken(JwtHeader header, JwtPayload payload) { if (header == null) { throw new ArgumentNullException("header"); } if (payload == null) { throw new ArgumentNullException("payload"); } this.header = header; this.payload = payload; }
public void JwtHeader_SigningKeyIdentifier() { var cert = KeyingMaterial.DefaultAsymmetricCert_2048; var header = new JwtHeader(new X509SigningCredentials(cert)); var payload = new JwtPayload( new Claim[]{new Claim("iss", "issuer")}); var jwt = new JwtSecurityToken(header, payload, header.Base64UrlEncode(), payload.Base64UrlEncode(), ""); var handler = new JwtSecurityTokenHandler(); var signedJwt = handler.WriteToken(jwt); SecurityToken token = null; var validationParameters = new TokenValidationParameters { IssuerSigningToken = new X509SecurityToken(cert), ValidateAudience = false, ValidateIssuer = false, ValidateLifetime = false, }; handler.ValidateToken(signedJwt, validationParameters, out token); validationParameters = new TokenValidationParameters { IssuerSigningKey = new X509SecurityKey(cert), ValidateAudience = false, ValidateIssuer = false, ValidateLifetime = false, }; handler.ValidateToken(signedJwt, validationParameters, out token); }
/// <inheritdoc /> /// <summary> /// Create a request with the claims in payload. /// </summary> /// <param name="payload"></param> public LtiDeepLinkingResponse(JwtPayload payload) : base(payload.Claims) { }
public void JwtPalyoad_ObjectClaims() { JwtPayload jwtPayload = new JwtPayload(); int? time = 10000; jwtPayload.Add("exp", time ); DateTime payloadTime = EpochTime.DateTime( time.Value ); DateTime payloadValidTo = jwtPayload.ValidTo; Assert.AreEqual(EpochTime.DateTime(time.Value), jwtPayload.ValidTo, "EpochTime.DateTime( time ) != jwtPayload.ValidTo"); int? expirationTime = jwtPayload.Exp; Assert.AreEqual(expirationTime, time, "expirationTime != time"); }
public static JwtSecurityToken Create(string issuer, string originalIssuer, SigningCredentials signingCredentials) { JwtPayload payload = new JwtPayload(issuer, "urn:uri", ClaimSets.Simple(issuer, originalIssuer), DateTime.UtcNow, DateTime.UtcNow + TimeSpan.FromHours(10)); JwtHeader header = new JwtHeader(signingCredentials); return new JwtSecurityToken(header, payload, header.Encode() + "." + payload.Encode() + "."); }
public static string ZoomToken(OrderParamModel model = null) { // Token will be good for 20 minutes DateTime Expiry = DateTime.UtcNow.AddMinutes(20); int ts = (int)(Expiry - new DateTime(1970, 1, 1)).TotalSeconds; var generator = new Random(); Byte[] b = new Byte[32]; generator.NextBytes(b); var tokenId = Convert.ToBase64String(b); // Create Security key using public key above: var securityKey = new Microsoft.IdentityModel.Tokens.SymmetricSecurityKey(Encoding.UTF8.GetBytes(PRO_API_SECRET)); // length should be >256b var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256Signature); //Finally create a Token var header = new JwtHeader(credentials); var payload = new JwtPayload(); if (model != null) { //Zoom Required Payload payload = new JwtPayload { { "iss", PRO_API_KEY }, { "exp", ts }, { "jti", tokenId }, { "form_params", new OrderParamModel { mrc_order_id = model.mrc_order_id, total_amount = model.total_amount, description = model.description, url_success = model.url_success, merchant_id = model.merchant_id, url_detail = model.url_detail, lang = model.lang, bpm_id = model.bpm_id, accept_bank = model.accept_bank, accept_cc = model.accept_cc, accept_qrpay = model.accept_qrpay, accept_e_wallet = model.accept_e_wallet, webhooks = model.webhooks, customer_email = model.customer_email, customer_phone = model.customer_phone, customer_name = model.customer_name, customer_address = model.customer_address } } }; } else { payload = new JwtPayload { { "iss", PRO_API_KEY }, { "exp", ts }, { "jti", tokenId } }; } var secToken = new JwtSecurityToken(header, payload); var handler = new JwtSecurityTokenHandler(); // Token to String so you can use it in your client var tokenString = handler.WriteToken(secToken); return(tokenString); }
public void CreateAndValidateTokens_MultipleAudiences() { List<string> errors = new List<string>(); var handler = new JwtSecurityTokenHandler(); var payload = new JwtPayload(); var header = new JwtHeader(); payload.AddClaims(ClaimSets.MultipleAudiences(IdentityUtilities.DefaultIssuer, IdentityUtilities.DefaultIssuer)); var jwtToken = new JwtSecurityToken(header, payload); var jwt = handler.WriteToken(jwtToken); var validationParameters = new TokenValidationParameters { RequireExpirationTime = false, RequireSignedTokens = false, ValidateAudience = false, ValidateIssuer = false, ValidateLifetime = false, }; SecurityToken validatedJwt = null; var cp = handler.ValidateToken(jwt, validationParameters, out validatedJwt); var ci = new ClaimsIdentity(ClaimSets.MultipleAudiences(IdentityUtilities.DefaultIssuer, IdentityUtilities.DefaultIssuer), AuthenticationTypes.Federation); var cpExpected = new ClaimsPrincipal(ci); var compareContext = new CompareContext(); if (!IdentityComparer.AreEqual<ClaimsPrincipal>(cp, cpExpected, compareContext)) { errors.Add("IdentityComparer.AreEqual<ClaimsPrincipal>(cp, cpExpected, compareContext)"); } var audiences = (validatedJwt as JwtSecurityToken).Audiences; var jwtAudiences = jwtToken.Audiences; if (!IdentityComparer.AreEqual<IEnumerable<string>>(audiences, jwtAudiences)) { errors.Add("!IdentityComparer.AreEqual<IEnumerable<string>>(audiences, jwtAudiences)"); } if (!IdentityComparer.AreEqual<IEnumerable<string>>(audiences, IdentityUtilities.DefaultAudiences)) { errors.Add("!IdentityComparer.AreEqual<IEnumerable<string>>(audiences, IdentityUtilities.DefaultAudiences)"); } TestUtilities.AssertFailIfErrors(MethodInfo.GetCurrentMethod().Name, errors); }
/// <summary> /// Initializes a new instance of the <see cref="JwtSecurityToken"/> class specifying optional parameters. /// </summary> /// <param name="issuer">if this value is not null, a { iss, 'issuer' } claim will be added.</param> /// <param name="audience">if this value is not null, a { aud, 'audience' } claim will be added</param> /// <param name="claims">if this value is not null then for each <see cref="Claim"/> a { 'Claim.Type', 'Claim.Value' } is added. If duplicate claims are found then a { 'Claim.Type', List<object> } will be created to contain the duplicate values.</param> /// <param name="expires">if expires.HasValue a { exp, 'value' } claim is added.</param> /// <param name="notBefore">if notbefore.HasValue a { nbf, 'value' } claim is added.</param> /// <param name="signingCredentials">The <see cref="SigningCredentials"/> that will be used to sign the <see cref="JwtSecurityToken"/>. See <see cref="JwtHeader(SigningCredentials)"/> for details pertaining to the Header Parameter(s).</param> /// <exception cref="ArgumentException">if 'expires' <= 'notbefore'.</exception> public JwtSecurityToken(string issuer = null, string audience = null, IEnumerable<Claim> claims = null, DateTime? notBefore = null, DateTime? expires = null, SigningCredentials signingCredentials = null) { if (expires.HasValue && notBefore.HasValue) { if (notBefore >= expires) { throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, ErrorMessages.IDX10401, expires.Value, notBefore.Value)); } } this.payload = new JwtPayload(issuer: issuer, audience: audience, claims: claims, notBefore: notBefore, expires: expires); this.header = new JwtHeader(signingCredentials); }
public async Task <IActionResult> Post([FromBody] LoginViewModel User) { try { var account = await _accountService.Authenticate(User.Username, User.Password); if (account == null) { Dictionary <string, object> Result = new ResultFormatter(ApiVersion, General.NOT_FOUND_STATUS_CODE, General.NOT_FOUND_MESSAGE) .Fail(); return(NotFound(Result)); } else { AccountViewModel viewModel = Mapper.Map <AccountViewModel>(account); SymmetricSecurityKey securityKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(Secret)); var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256); var header = new JwtHeader(credentials); var payload = new JwtPayload { { "username", viewModel.username } }; payload["profile"] = new { viewModel.profile.firstname, viewModel.profile.lastname, viewModel.profile.gender, viewModel.profile.dob, viewModel.profile.email }; string jsonRes = "{"; if (viewModel.roles.Count > 0) { foreach (var item in viewModel.roles.SelectMany(x => x.permissions).GroupBy(x => x.jobTitle.Code).Select(g => g.First())) { jsonRes = jsonRes + "'" + item.jobTitle.Code + "'" + " : " + item.permission + ","; } jsonRes = jsonRes.Remove(jsonRes.Length - 1); } jsonRes += "}"; var jsonObject = JObject.Parse(jsonRes); payload["permission"] = jsonObject; payload["iat"] = DateTimeOffset.UtcNow.ToUnixTimeSeconds(); var secToken = new JwtSecurityToken(header, payload); var handler = new JwtSecurityTokenHandler(); var tokenString = handler.WriteToken(secToken); Dictionary <string, object> Result = new ResultFormatter(ApiVersion, General.OK_STATUS_CODE, General.OK_MESSAGE) .Ok(); Result.Add("data", tokenString); return(Ok(Result)); } } catch (Exception ex) { Dictionary <string, object> Result = new ResultFormatter(ApiVersion, General.BAD_REQUEST_STATUS_CODE, ex.Message) .Fail(); return(BadRequest(Result)); } }
/// <summary> /// Get the payload claim value as a string. /// </summary> /// <returns>The claim value as a string.</returns> public static string GetClaimValue(this JwtPayload payload, string type) { return(GetClaimValue <string>(payload, type)); }
/// <summary> /// Decodes the string into the header, payload and signature /// </summary> /// <param name="jwtEncodedString">Base64Url encoded string.</param> internal void Decode(string jwtEncodedString) { string[] tokenParts = jwtEncodedString.Split('.'); if (tokenParts.Length != 3) { throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, ErrorMessages.IDX10709, "jwtEncodedString", jwtEncodedString)); } try { this.header = Base64UrlEncoder.Decode(tokenParts[0]).DeserializeJwtHeader(); // if present, "typ" should be set to "JWT" or "http://openid.net/specs/jwt/1.0" string type = null; if (this.header.TryGetValue(JwtHeaderParameterNames.Typ, out type)) { if (!(StringComparer.Ordinal.Equals(type, JwtConstants.HeaderType) || StringComparer.Ordinal.Equals(type, JwtConstants.HeaderTypeAlt))) { throw new SecurityTokenException(string.Format(CultureInfo.InvariantCulture, ErrorMessages.IDX10702, JwtConstants.HeaderType, JwtConstants.HeaderTypeAlt, type)); } } } catch (Exception ex) { if (DiagnosticUtility.IsFatal(ex)) { throw; } throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, ErrorMessages.IDX10703, "header", tokenParts[0], jwtEncodedString), ex); } try { this.payload = Base64UrlEncoder.Decode(tokenParts[1]).DeserializeJwtPayload(); } catch (Exception ex) { if (DiagnosticUtility.IsFatal(ex)) { throw; } throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, ErrorMessages.IDX10703, "payload", tokenParts[1], jwtEncodedString), ex); } this.rawData = jwtEncodedString; this.signature = tokenParts[2]; }
/// <summary> /// Uses the <see cref="JwtSecurityToken(JwtHeader, JwtPayload, string, string, string)"/> constructor, first creating the <see cref="JwtHeader"/> and <see cref="JwtPayload"/>. /// <para>If <see cref="SigningCredentials"/> is not null, <see cref="JwtSecurityToken.RawData"/> will be signed.</para> /// </summary> /// <param name="issuer">the issuer of the token.</param> /// <param name="audience">the audience for this token.</param> /// <param name="subject">the source of the <see cref="Claim"/>(s) for this token.</param> /// <param name="notBefore">the notbefore time for this token.</param> /// <param name="expires">the expiration time for this token.</param> /// <param name="signingCredentials">contains cryptographic material for generating a signature.</param> /// <param name="signatureProvider">optional <see cref="SignatureProvider"/>.</param> /// <remarks>If <see cref="ClaimsIdentity.Actor"/> is not null, then a claim { actort, 'value' } will be added to the payload. <see cref="CreateActorValue"/> for details on how the value is created. /// <para>See <seealso cref="JwtHeader"/> for details on how the HeaderParameters are added to the header.</para> /// <para>See <seealso cref="JwtPayload"/> for details on how the values are added to the payload.</para></remarks> /// <para>If signautureProvider is not null, then it will be used to create the signature and <see cref="System.IdentityModel.Tokens.SignatureProviderFactory.CreateForSigning( SecurityKey, string )"/> will not be called.</para> /// <returns>A <see cref="JwtSecurityToken"/>.</returns> /// <exception cref="ArgumentException">if 'expires' <= 'notBefore'.</exception> public virtual JwtSecurityToken CreateToken(string issuer = null, string audience = null, ClaimsIdentity subject = null, DateTime? notBefore = null, DateTime? expires = null, SigningCredentials signingCredentials = null, SignatureProvider signatureProvider = null) { if (expires.HasValue && notBefore.HasValue) { if (notBefore >= expires) { throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, ErrorMessages.IDX10401, expires.Value, notBefore.Value)); } } // if not set, use defaults if (!expires.HasValue && !notBefore.HasValue) { DateTime now = DateTime.UtcNow; expires = now + TimeSpan.FromMinutes(TokenLifetimeInMinutes); notBefore = now; } JwtPayload payload = new JwtPayload(issuer, audience, subject == null ? null : subject.Claims, notBefore, expires); JwtHeader header = new JwtHeader(signingCredentials); if (subject != null && subject.Actor != null) { payload.AddClaim(new Claim(JwtRegisteredClaimNames.Actort, this.CreateActorValue(subject.Actor))); } string rawHeader = header.Base64UrlEncode(); string rawPayload = payload.Base64UrlEncode(); string rawSignature = string.Empty; string signingInput = string.Concat(rawHeader, ".", rawPayload); if (signatureProvider != null) { rawSignature = Base64UrlEncoder.Encode(this.CreateSignature(signingInput, null, null, signatureProvider)); } else if (signingCredentials != null) { rawSignature = Base64UrlEncoder.Encode(this.CreateSignature(signingInput, signingCredentials.SigningKey, signingCredentials.SignatureAlgorithm, signatureProvider)); } return new JwtSecurityToken(header, payload, rawHeader, rawPayload, rawSignature); }
/// <summary> /// Initializes a new instance of the <see cref="JwtSecurityToken"/> class where the <see cref="JwtHeader"/> contains the crypto algorithms applied to the encoded <see cref="JwtHeader"/> and <see cref="JwtPayload"/>. The jwtEncodedString is the result of those operations. /// </summary> /// <param name="header">Contains JSON objects representing the cryptographic operations applied to the JWT and optionally any additional properties of the JWT</param> /// <param name="payload">Contains JSON objects representing the claims contained in the JWT. Each claim is a JSON object of the form { Name, Value }</param> /// <param name="jwtEncodedString">The results of encoding and applying the cryptographic operations to the <see cref="JwtHeader"/> and <see cref="JwtPayload"/>.</param> /// <exception cref="ArgumentNullException">'header' is null.</exception> /// <exception cref="ArgumentNullException">'payload' is null.</exception> /// <exception cref="ArgumentNullException">'jwtEncodedString' is null.</exception> /// <exception cref="ArgumentException">'jwtEncodedString' contains only whitespace.</exception> /// <exception cref="ArgumentException">'jwtEncodedString' is not in JWS Compact serialized format.</exception> public JwtSecurityToken(JwtHeader header, JwtPayload payload, string jwtEncodedString) { if (header == null) { throw new ArgumentNullException("header"); } if (payload == null) { throw new ArgumentNullException("payload"); } if (jwtEncodedString == null) { throw new ArgumentNullException("jwtEncodedString"); } if (string.IsNullOrWhiteSpace(jwtEncodedString)) { throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, ErrorMessages.IDX10002, "jwtEncodedString")); } if (!Regex.IsMatch(jwtEncodedString, JwtConstants.JsonCompactSerializationRegex)) { throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, ErrorMessages.IDX10709, "jwtEncodedString", jwtEncodedString)); } string[] tokenParts = jwtEncodedString.Split('.'); if (tokenParts.Length != 3) { throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, ErrorMessages.IDX10709, "jwtEncodedString", jwtEncodedString)); } this.header = header; this.payload = payload; this.rawData = jwtEncodedString; this.signature = tokenParts[2]; }
/// <summary> /// Creates the JWT payload /// </summary> /// <param name="token">The token.</param> /// <returns>The JWT payload</returns> protected virtual JwtPayload CreatePayload(Token token) { var payload = new JwtPayload( token.Issuer, token.Audience, null, DateTimeHelper.UtcNow, DateTimeHelper.UtcNow.AddSeconds(token.Lifetime)); var amrClaims = token.Claims.Where(x => x.Type == Constants.ClaimTypes.AuthenticationMethod); var jsonClaims = token.Claims.Where(x => x.ValueType == Constants.ClaimValueTypes.Json); var normalClaims = token.Claims.Except(amrClaims).Except(jsonClaims); payload.AddClaims(normalClaims); // deal with amr var amrValues = amrClaims.Select(x => x.Value).Distinct().ToArray(); if (amrValues.Any()) { payload.Add(Constants.ClaimTypes.AuthenticationMethod, amrValues); } // deal with json types // calling ToArray() to trigger JSON parsing once and so later // collection identity comparisons work for the anonymous type var jsonTokens = jsonClaims.Select(x => new { x.Type, JsonValue = JRaw.Parse(x.Value) }).ToArray(); var jsonObjects = jsonTokens.Where(x => x.JsonValue.Type == JTokenType.Object).ToArray(); var jsonObjectGroups = jsonObjects.GroupBy(x=>x.Type).ToArray(); foreach(var group in jsonObjectGroups) { if (payload.ContainsKey(group.Key)) { throw new Exception(String.Format("Can't add two claims where one is a JSON object and the other is not a JSON object ({0})", group.Key)); } if (group.Skip(1).Any()) { // add as array payload.Add(group.Key, group.Select(x=>x.JsonValue).ToArray()); } else { // add just one payload.Add(group.Key, group.First().JsonValue); } } var jsonArrays = jsonTokens.Where(x => x.JsonValue.Type == JTokenType.Array).ToArray(); var jsonArrayGroups = jsonArrays.GroupBy(x=>x.Type).ToArray(); foreach (var group in jsonArrayGroups) { if (payload.ContainsKey(group.Key)) { throw new Exception(String.Format("Can't add two claims where one is a JSON array and the other is not a JSON array ({0})", group.Key)); } List<JToken> newArr = new List<JToken>(); foreach(var arrays in group) { var arr = (JArray)arrays.JsonValue; newArr.AddRange(arr); } // add just one array for the group/key/claim type payload.Add(group.Key, newArr.ToArray()); } var unsupportedJsonTokens = jsonTokens.Except(jsonObjects).Except(jsonArrays); var unsupportedJsonClaimTypes = unsupportedJsonTokens.Select(x => x.Type).Distinct(); if (unsupportedJsonClaimTypes.Any()) { throw new Exception(String.Format("Unsupported JSON type for claim types: {0}", unsupportedJsonClaimTypes.Aggregate((x, y) => x + ", " + y))); } return payload; }
public static JwtSecurityToken CreateJwtSecurityToken(string issuer, string originalIssuer, IEnumerable<Claim> claims, SigningCredentials signingCredentials) { JwtPayload payload = new JwtPayload(issuer, "urn:uri", claims, DateTime.UtcNow, DateTime.UtcNow + TimeSpan.FromHours(10)); JwtHeader header = new JwtHeader(signingCredentials); return new JwtSecurityToken(header, payload); }