/// <summary> /// Validates the JWT signature. /// </summary> private JsonWebToken ValidateSignature(string token, TokenValidationParameters validationParameters) { if (string.IsNullOrWhiteSpace(token)) { throw LogHelper.LogArgumentNullException(nameof(token)); } if (validationParameters == null) { throw LogHelper.LogArgumentNullException(nameof(validationParameters)); } if (validationParameters.SignatureValidator != null) { var validatedToken = validationParameters.SignatureValidator(token, validationParameters); if (validatedToken == null) { throw LogHelper.LogExceptionMessage(new SecurityTokenInvalidSignatureException(LogHelper.FormatInvariant(TokenLogMessages.IDX10505, token))); } var validatedJsonWebToken = validatedToken as JsonWebToken; if (validatedJsonWebToken == null) { throw LogHelper.LogExceptionMessage(new SecurityTokenInvalidSignatureException(LogHelper.FormatInvariant(TokenLogMessages.IDX10506, typeof(JsonWebToken), validatedJsonWebToken.GetType(), token))); } return(validatedJsonWebToken); } JsonWebToken jwtToken = null; if (validationParameters.TokenReader != null) { var securityToken = validationParameters.TokenReader(token, validationParameters); if (securityToken == null) { throw LogHelper.LogExceptionMessage(new SecurityTokenInvalidSignatureException(LogHelper.FormatInvariant(TokenLogMessages.IDX10510, token))); } jwtToken = securityToken as JsonWebToken; if (jwtToken == null) { throw LogHelper.LogExceptionMessage(new SecurityTokenInvalidSignatureException(LogHelper.FormatInvariant(TokenLogMessages.IDX10509, typeof(JsonWebToken), securityToken.GetType(), token))); } } else { jwtToken = new JsonWebToken(token); } string[] tokenParts = jwtToken.EncodedToken.Split(new char[] { '.' }, JwtConstants.MaxJwtSegmentCount + 1); byte[] encodedBytes = Encoding.UTF8.GetBytes(tokenParts[0] + "." + tokenParts[1]); if (string.IsNullOrEmpty(tokenParts[2])) { if (validationParameters.RequireSignedTokens) { throw LogHelper.LogExceptionMessage(new SecurityTokenInvalidSignatureException(LogHelper.FormatInvariant(TokenLogMessages.IDX10504, token))); } else { return(jwtToken); } } bool kidMatched = false; IEnumerable <SecurityKey> keys = null; if (validationParameters.IssuerSigningKeyResolver != null) { keys = validationParameters.IssuerSigningKeyResolver(token, jwtToken, jwtToken.Kid, validationParameters); } else { var key = ResolveIssuerSigningKey(jwtToken, validationParameters); if (key != null) { kidMatched = true; keys = new List <SecurityKey> { key }; } } if (keys == null) { // control gets here if: // 1. User specified delegate: IssuerSigningKeyResolver returned null // 2. ResolveIssuerSigningKey returned null // Try all the keys. This is the degenerate case, not concerned about perf. keys = GetAllSigningKeys(token, validationParameters); } // keep track of exceptions thrown, keys that were tried var exceptionStrings = new StringBuilder(); var keysAttempted = new StringBuilder(); bool kidExists = !string.IsNullOrEmpty(jwtToken.Kid); byte[] signatureBytes; try { signatureBytes = Base64UrlEncoder.DecodeBytes(tokenParts[2]); } catch (FormatException e) { throw new SecurityTokenInvalidSignatureException(TokenLogMessages.IDX10508, e); } foreach (var key in keys) { try { if (ValidateSignature(encodedBytes, signatureBytes, key, jwtToken.Alg, validationParameters)) { LogHelper.LogInformation(TokenLogMessages.IDX10242, token); jwtToken.SigningKey = key; return(jwtToken); } ; } catch (Exception ex) { exceptionStrings.AppendLine(ex.ToString()); } if (key != null) { keysAttempted.AppendLine(key.ToString() + " , KeyId: " + key.KeyId); if (kidExists && !kidMatched && key.KeyId != null) { kidMatched = jwtToken.Kid.Equals(key.KeyId, key is X509SecurityKey ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal); } } } if (kidExists) { if (kidMatched) { throw LogHelper.LogExceptionMessage(new SecurityTokenInvalidSignatureException(LogHelper.FormatInvariant(TokenLogMessages.IDX10511, keysAttempted, jwtToken.Kid, exceptionStrings, jwtToken))); } else { throw LogHelper.LogExceptionMessage(new SecurityTokenSignatureKeyNotFoundException(LogHelper.FormatInvariant(TokenLogMessages.IDX10501, jwtToken.Kid, jwtToken))); } } else { if (keysAttempted.Length > 0) { throw LogHelper.LogExceptionMessage(new SecurityTokenInvalidSignatureException(LogHelper.FormatInvariant(TokenLogMessages.IDX10503, keysAttempted, exceptionStrings, jwtToken))); } else { throw LogHelper.LogExceptionMessage(new SecurityTokenSignatureKeyNotFoundException(TokenLogMessages.IDX10500)); } } }