public override SecurityToken CreateToken(SecurityTokenDescriptor descriptor) { var jwt = new JsonWebToken(); if (descriptor.SigningCredentials == null) { jwt.Header.SignatureAlgorithm = JwtConstants.SignatureAlgorithms.None; } else { var algorithm = ParseSigningCredentials(descriptor.SigningCredentials); jwt.Header.SigningCredentials = descriptor.SigningCredentials; jwt.Header.SignatureAlgorithm = algorithm; } if (!string.IsNullOrWhiteSpace(descriptor.TokenIssuerName)) { jwt.Issuer = descriptor.TokenIssuerName; } if (descriptor.Lifetime != null) { jwt.ExpirationTime = descriptor.Lifetime.Expires.Value.ToEpochTime(); } if (!string.IsNullOrWhiteSpace(descriptor.AppliesToAddress)) { jwt.Audience = new Uri(descriptor.AppliesToAddress); } if (descriptor.Subject != null) { foreach (var claim in descriptor.Subject.Claims) { jwt.AddClaim(claim.Type, claim.Value); } } return jwt; }
protected virtual void VerifySignature(JsonWebToken jwt, SecurityKey signingKey) { var key = signingKey as InMemorySymmetricSecurityKey; if (key == null) { throw new SecurityTokenValidationException("Unsupported signing key."); } string verifySignature; using (var algorithm = key.GetKeyedHashAlgorithm(ValidateHmacAlgorithm(key.KeySize, jwt.Header.SignatureAlgorithm))) { verifySignature = Base64Url.Encode(algorithm.ComputeHash(Encoding.UTF8.GetBytes(jwt.UnsignedToken))); } if (!(ObfuscatingComparer.IsEqual(verifySignature, jwt.Signature))) { throw new SecurityTokenValidationException("Invalid signature."); } }
protected virtual ClaimsIdentity CreateClaimsIdentity(JsonWebToken jwt) { var claims = new List<Claim>(); foreach (var item in jwt.Claims) { if (item.Value.Contains(',')) { var items = item.Value.Split(','); foreach (var part in items) { claims.Add(new Claim(item.Key, part, ClaimValueTypes.String, jwt.Issuer)); } } else { claims.Add(new Claim(item.Key, item.Value, ClaimValueTypes.String, jwt.Issuer)); } } //var claims = new List<Claim>( // from c in jwt.Claims // select new Claim(c.Type, c.Value, c.ValueType, jwt.Issuer)); if (!string.IsNullOrWhiteSpace(jwt.Principal)) { claims.Add(new Claim("prn", jwt.Principal, ClaimValueTypes.String, jwt.Issuer)); } if (jwt.IssuedAt.HasValue) { claims.Add(new Claim("iat", jwt.IssuedAt.Value.ToString(), ClaimValueTypes.String, jwt.Issuer)); } return new ClaimsIdentity(claims, "JWT"); }
protected virtual void ReadHeader(string header, JsonWebToken jwt) { var json = JObject.Load(new JsonTextReader(new StringReader(header))); var typ = json[JwtConstants.Header.Type]; if (typ != null && !string.IsNullOrWhiteSpace(typ.ToString())) { jwt.Header.Type = typ.ToString(); } var alg = json[JwtConstants.Header.Algorithm]; if (alg == null || string.IsNullOrEmpty(alg.ToString())) { throw new SecurityTokenException("Algorithm header is missing."); } jwt.Header.SignatureAlgorithm = alg.ToString(); }
protected virtual void ReadClaims(string claims, JsonWebToken jwt) { var json = JObject.Load(new JsonTextReader(new StringReader(claims))); foreach (var item in json) { switch (item.Key) { case JwtConstants.Claims.Audience: jwt.Audience = new Uri(item.Value.ToString()); break; case JwtConstants.Claims.ExpirationTime: jwt.ExpirationTime = long.Parse(item.Value.ToString()); break; case JwtConstants.Claims.IssuedAt: jwt.IssuedAt = long.Parse(item.Value.ToString()); break; case JwtConstants.Claims.Issuer: jwt.Issuer = item.Value.ToString(); break; case JwtConstants.Claims.NotBefore: jwt.NotBefore = long.Parse(item.Value.ToString()); break; case JwtConstants.Claims.Principal: jwt.Principal = item.Value.ToString(); break; default: jwt.Claims.Add(item.Key, item.Value.ToString()); break; } } }
public override SecurityToken ReadToken(string tokenString) { if (string.IsNullOrWhiteSpace(tokenString)) { throw new ArgumentNullException("tokenString"); } var jwt = new JsonWebToken(); var parts = tokenString.Split('.'); if (parts.Length < 2) { tokenString = Encoding.UTF8.GetString(Base64Url.Decode(tokenString)); parts = tokenString.Split('.'); } if (parts.Length < 2) { throw new SecurityTokenException("Malformed token"); } var encodedHeader = parts[0]; var encodedClaims = parts[1]; ReadHeader(Encoding.UTF8.GetString(Base64Url.Decode(encodedHeader)), jwt); string signature = string.Empty; if (jwt.Header.SignatureAlgorithm != JwtConstants.SignatureAlgorithms.None) { if (parts.Length != 3) { throw new SecurityTokenException("Signature is missing"); } signature = parts[2]; } jwt.UnsignedToken = string.Format("{0}.{1}", encodedHeader, encodedClaims); jwt.Signature = signature; ReadClaims(Encoding.UTF8.GetString(Base64Url.Decode(encodedClaims)), jwt); return jwt; }
protected virtual void AddUserClaims(JsonWebToken jwt, JsonTextWriter writer) { foreach (var claim in jwt.Claims) { writer.WritePropertyName(claim.Key); writer.WriteValue(claim.Value); } }
protected virtual void AddReservedClaims(JsonWebToken jwt, JsonTextWriter writer) { // exp if (jwt.ExpirationTime.HasValue) { writer.WritePropertyName(JwtConstants.Claims.ExpirationTime); writer.WriteValue(jwt.ExpirationTime.Value); } // nbf if (jwt.NotBefore.HasValue) { writer.WritePropertyName(JwtConstants.Claims.NotBefore); writer.WriteValue(jwt.NotBefore.Value); } // iat if (jwt.IssuedAt.HasValue) { writer.WritePropertyName(JwtConstants.Claims.IssuedAt); writer.WriteValue(jwt.IssuedAt.Value); } // iss if (!string.IsNullOrWhiteSpace(jwt.Issuer)) { writer.WritePropertyName(JwtConstants.Claims.Issuer); writer.WriteValue(jwt.Issuer); } // aud if (jwt.Audience != null) { writer.WritePropertyName(JwtConstants.Claims.Audience); writer.WriteValue(jwt.Audience.AbsoluteUri); } // prn if (!string.IsNullOrWhiteSpace(jwt.Principal)) { writer.WritePropertyName(JwtConstants.Claims.Principal); writer.WriteValue(jwt.Principal); } // jti if (!string.IsNullOrWhiteSpace(jwt.JwtId)) { writer.WritePropertyName(JwtConstants.Claims.Id); writer.WriteValue(jwt.JwtId); } }
protected virtual string CreateClaimSet(JsonWebToken jwt) { StringBuilder sb = new StringBuilder(); StringWriter sw = new StringWriter(sb); using (var jsonWriter = new JsonTextWriter(sw)) { jsonWriter.WriteStartObject(); AddReservedClaims(jwt, jsonWriter); AddUserClaims(jwt, jsonWriter); jsonWriter.WriteEndObject(); } var json = sb.ToString(); Debug.WriteLine(json); return Base64Url.Encode(Encoding.UTF8.GetBytes(json)); }
protected virtual string CreateHeader(JsonWebToken jwt) { StringBuilder sb = new StringBuilder(); StringWriter sw = new StringWriter(sb); using (JsonWriter jsonWriter = new JsonTextWriter(sw)) { jsonWriter.WriteStartObject(); jsonWriter.WritePropertyName(JwtConstants.Header.Type); jsonWriter.WriteValue(jwt.Header.Type); jsonWriter.WritePropertyName(JwtConstants.Header.Algorithm); jsonWriter.WriteValue(jwt.Header.SignatureAlgorithm); jsonWriter.WriteEndObject(); } var json = sb.ToString(); Debug.WriteLine(json); return Base64Url.Encode(Encoding.UTF8.GetBytes(json)); }