diff --git a/src/Microsoft.IdentityModel.Tokens/Validation/ValidationParameters.cs b/src/Microsoft.IdentityModel.Tokens/Validation/ValidationParameters.cs index c064531798..0ae2048f06 100644 --- a/src/Microsoft.IdentityModel.Tokens/Validation/ValidationParameters.cs +++ b/src/Microsoft.IdentityModel.Tokens/Validation/ValidationParameters.cs @@ -29,6 +29,7 @@ internal class ValidationParameters private LifetimeValidatorDelegate _lifetimeValidator = Validators.ValidateLifetime; private TokenReplayValidatorDelegate _tokenReplayValidator = Validators.ValidateTokenReplay; private TypeValidatorDelegate _typeValidator = Validators.ValidateTokenType; + private IssuerSigningKeyValidatorDelegate _issuerSigningKeyValidator = Validators.ValidateIssuerSigningKey; /// /// This is the default value of when creating a . @@ -269,7 +270,11 @@ public virtual ClaimsIdentity CreateClaimsIdentity(SecurityToken securityToken, /// If both and are set, IssuerSigningKeyResolverUsingConfiguration takes /// priority. /// - public IssuerSigningKeyValidator IssuerSigningKeyValidator { get; set; } + public IssuerSigningKeyValidatorDelegate IssuerSigningKeyValidator + { + get => _issuerSigningKeyValidator; + set => _issuerSigningKeyValidator = value ?? throw new ArgumentNullException(nameof(value), "IssuerSigningKeyValidator cannot be set as null."); + } /// /// Gets a that is unique to this instance. diff --git a/src/Microsoft.IdentityModel.Tokens/Validation/Validators.IssuerSecurityKey.cs b/src/Microsoft.IdentityModel.Tokens/Validation/Validators.IssuerSigningKey.cs similarity index 54% rename from src/Microsoft.IdentityModel.Tokens/Validation/Validators.IssuerSecurityKey.cs rename to src/Microsoft.IdentityModel.Tokens/Validation/Validators.IssuerSigningKey.cs index 9adcde0db3..15d4f615f4 100644 --- a/src/Microsoft.IdentityModel.Tokens/Validation/Validators.IssuerSecurityKey.cs +++ b/src/Microsoft.IdentityModel.Tokens/Validation/Validators.IssuerSigningKey.cs @@ -17,17 +17,17 @@ namespace Microsoft.IdentityModel.Tokens /// /// The security key to validate. /// The that is being validated. - /// The to be used for validating the token. - /// - /// + /// The to be used for validating the token. + /// The to be used for validation. + /// The to be used for logging. /// A that contains the results of validating the issuer. /// This delegate is not expected to throw. - internal delegate Task IssuerSecurityKeyValidationDelegate( + internal delegate SigningKeyValidationResult IssuerSigningKeyValidatorDelegate( SecurityKey signingKey, SecurityToken securityToken, - TokenValidationParameters validationParameters, - CallContext callContext, - CancellationToken cancellationToken); + ValidationParameters validationParameters, + BaseConfiguration? configuration, + CallContext? callContext); /// /// SigningKeyValidation @@ -40,28 +40,20 @@ public static partial class Validators /// /// The that signed the . /// The being validated. - /// The to be used for validating the token. - /// + /// The to be used for validating the token. + /// The to be used for validation. + /// The to be used for logging. /// if 'securityKey' is null and ValidateIssuerSigningKey is true. /// if 'securityToken' is null and ValidateIssuerSigningKey is true. /// if 'validationParameters' is null. - internal static SigningKeyValidationResult ValidateIssuerSecurityKey(SecurityKey securityKey, SecurityToken securityToken, TokenValidationParameters validationParameters, CallContext callContext) - { - return ValidateIssuerSecurityKey(securityKey, securityToken, validationParameters, null, callContext); - } - - /// - /// Validates the that signed a . - /// - /// The that signed the . - /// The being validated. - /// The to be used for validating the token. - /// The required for issuer and signing key validation. - /// - /// if 'securityKey' is null and ValidateIssuerSigningKey is true. - /// if 'securityToken' is null and ValidateIssuerSigningKey is true. - /// if 'validationParameters' is null. - internal static SigningKeyValidationResult ValidateIssuerSecurityKey(SecurityKey securityKey, SecurityToken securityToken, TokenValidationParameters validationParameters, BaseConfiguration? configuration, CallContext callContext) + internal static SigningKeyValidationResult ValidateIssuerSigningKey( + SecurityKey securityKey, + SecurityToken securityToken, + ValidationParameters validationParameters, +#pragma warning disable CA1801 // Review unused parameters + BaseConfiguration? configuration, +#pragma warning restore CA1801 // Review unused parameters + CallContext? callContext) { if (validationParameters == null) return new SigningKeyValidationResult( @@ -74,28 +66,7 @@ internal static SigningKeyValidationResult ValidateIssuerSecurityKey(SecurityKey typeof(ArgumentNullException), new StackFrame(true))); - if (validationParameters.IssuerSigningKeyValidatorUsingConfiguration != null) - { - return ValidateSigningKeyUsingDelegateAndConfiguration(securityKey, securityToken, validationParameters, configuration); - } - - if (validationParameters.IssuerSigningKeyValidator != null) - { - return ValidateSigningKeyUsingDelegateAndConfiguration(securityKey, securityToken, validationParameters, null); - } - - if (!validationParameters.ValidateIssuerSigningKey) - { - LogHelper.LogVerbose(LogMessages.IDX10237); - return new SigningKeyValidationResult(securityKey); - } - - if (!validationParameters.RequireSignedTokens && securityKey == null) - { - LogHelper.LogInformation(LogMessages.IDX10252); - return new SigningKeyValidationResult(securityKey); - } - else if (securityKey == null) + if (securityKey == null) { return new SigningKeyValidationResult( securityKey, @@ -126,10 +97,13 @@ internal static SigningKeyValidationResult ValidateIssuerSecurityKey(SecurityKey /// Given a signing key, when it's derived from a certificate, validates that the certificate is already active and non-expired /// /// The that signed the . - /// The to be used for validating the token. + /// The to be used for validating the token. /// #pragma warning disable CA1801 // Review unused parameters - internal static SigningKeyValidationResult ValidateIssuerSigningKeyLifeTime(SecurityKey securityKey, TokenValidationParameters validationParameters, CallContext callContext) + internal static SigningKeyValidationResult ValidateIssuerSigningKeyLifeTime( + SecurityKey securityKey, + ValidationParameters validationParameters, + CallContext? callContext) #pragma warning restore CA1801 // Review unused parameters { X509SecurityKey? x509SecurityKey = securityKey as X509SecurityKey; @@ -174,46 +148,6 @@ internal static SigningKeyValidationResult ValidateIssuerSigningKeyLifeTime(Secu return new SigningKeyValidationResult(securityKey); } - - private static SigningKeyValidationResult ValidateSigningKeyUsingDelegateAndConfiguration(SecurityKey securityKey, SecurityToken securityToken, TokenValidationParameters validationParameters, BaseConfiguration? configuration) - { - try - { - bool success; - if (configuration != null) - success = validationParameters.IssuerSigningKeyValidatorUsingConfiguration(securityKey, securityToken, validationParameters, configuration); - else - success = validationParameters.IssuerSigningKeyValidator(securityKey, securityToken, validationParameters); - - if (!success) - return new SigningKeyValidationResult( - securityKey, - ValidationFailureType.SigningKeyValidationFailed, - new ExceptionDetail( - new MessageDetail( - LogMessages.IDX10232, - securityKey), - typeof(SecurityTokenInvalidSigningKeyException), - new StackFrame(true))); - - return new SigningKeyValidationResult(securityKey); - } -#pragma warning disable CA1031 // Do not catch general exception types - catch (Exception exception) -#pragma warning restore CA1031 // Do not catch general exception types - { - return new SigningKeyValidationResult( - securityKey, - ValidationFailureType.SigningKeyValidationFailed, - new ExceptionDetail( - new MessageDetail( - LogMessages.IDX10232, - securityKey), - exception.GetType(), - new StackFrame(true), - exception)); - } - } } } #nullable restore diff --git a/test/Microsoft.IdentityModel.Tokens.Tests/Validation/SigningKeyValidationResultTests.cs b/test/Microsoft.IdentityModel.Tokens.Tests/Validation/SigningKeyValidationResultTests.cs index 43a6d3e313..98e10456d0 100644 --- a/test/Microsoft.IdentityModel.Tokens.Tests/Validation/SigningKeyValidationResultTests.cs +++ b/test/Microsoft.IdentityModel.Tokens.Tests/Validation/SigningKeyValidationResultTests.cs @@ -18,7 +18,7 @@ public void SecurityKey(SigningKeyValidationTheoryData theoryData) { CompareContext context = TestUtilities.WriteHeader($"{this}.SigningKeyValidationResultTests", theoryData); - SigningKeyValidationResult signingKeyValidationResult = Validators.ValidateIssuerSecurityKey( + SigningKeyValidationResult signingKeyValidationResult = Validators.ValidateIssuerSigningKey( theoryData.SecurityKey, theoryData.SecurityToken, theoryData.ValidationParameters, @@ -50,83 +50,11 @@ public static TheoryData SigningKeyValidationTes { new SigningKeyValidationTheoryData { - TestId = "Valid_SecurityTokenIsPresent_ValidateIssuerSigningKeyIsTrue", + TestId = "Valid_SecurityTokenIsPresent", ExpectedException = ExpectedException.NoExceptionExpected, SecurityKey = KeyingMaterial.SymmetricSecurityKey2_256, SecurityToken = new JwtSecurityToken(), - ValidationParameters = new TokenValidationParameters { ValidateIssuerSigningKey = true }, - SigningKeyValidationResult = new SigningKeyValidationResult(KeyingMaterial.SymmetricSecurityKey2_256) - }, - new SigningKeyValidationTheoryData - { - TestId = "Valid_SecurityKeyIsNull_ValidateIssuerSigningKeyIsFalse", - ExpectedException = ExpectedException.NoExceptionExpected, - SecurityKey = null, - SecurityToken = new JwtSecurityToken(), - ValidationParameters = new TokenValidationParameters { ValidateIssuerSigningKey = false }, - SigningKeyValidationResult = new SigningKeyValidationResult(null) - }, - new SigningKeyValidationTheoryData - { - TestId = "Valid_SecurityTokenIsNull_ValidateIssuerSigningKeyIsFalse", - ExpectedException = ExpectedException.NoExceptionExpected, - SecurityKey = KeyingMaterial.SymmetricSecurityKey2_256, - SecurityToken = null, - ValidationParameters = new TokenValidationParameters { ValidateIssuerSigningKey = false }, - SigningKeyValidationResult = new SigningKeyValidationResult(KeyingMaterial.SymmetricSecurityKey2_256) - }, - new SigningKeyValidationTheoryData - { - TestId = "Valid_SecurityKeyIsNull_RequireSignedTokensIsFalse", - ExpectedException = ExpectedException.NoExceptionExpected, - SecurityKey = null, - SecurityToken = new JwtSecurityToken(), - ValidationParameters = new TokenValidationParameters { ValidateIssuerSigningKey = true, RequireSignedTokens = false }, - SigningKeyValidationResult = new SigningKeyValidationResult(null) - }, - new SigningKeyValidationTheoryData - { - TestId = "Valid_SecurityKeyIsPresent_RequireSignedTokensIsTrue", - ExpectedException = ExpectedException.NoExceptionExpected, - SecurityKey = KeyingMaterial.SymmetricSecurityKey2_256, - SecurityToken = new JwtSecurityToken(), - ValidationParameters = new TokenValidationParameters { ValidateIssuerSigningKey = true, RequireSignedTokens = true }, - SigningKeyValidationResult = new SigningKeyValidationResult(KeyingMaterial.SymmetricSecurityKey2_256) - }, - new SigningKeyValidationTheoryData - { - TestId = "Valid_SecurityKeyIsPresent_RequireSignedTokensIsFalse", - ExpectedException = ExpectedException.NoExceptionExpected, - SecurityKey = KeyingMaterial.SymmetricSecurityKey2_256, - SecurityToken = new JwtSecurityToken(), - ValidationParameters = new TokenValidationParameters { ValidateIssuerSigningKey = true, RequireSignedTokens = false }, - SigningKeyValidationResult = new SigningKeyValidationResult(KeyingMaterial.SymmetricSecurityKey2_256) - }, - new SigningKeyValidationTheoryData - { - TestId = "Valid_DelegateSet_ReturnsTrue", - ExpectedException = ExpectedException.NoExceptionExpected, - SecurityKey = KeyingMaterial.SymmetricSecurityKey2_256, - SecurityToken = new JwtSecurityToken(), - ValidationParameters = new TokenValidationParameters - { - ValidateIssuerSigningKey = true, - IssuerSigningKeyValidator = (SecurityKey securityKey, SecurityToken token, TokenValidationParameters validationParameters) => true - }, - SigningKeyValidationResult = new SigningKeyValidationResult(KeyingMaterial.SymmetricSecurityKey2_256) - }, - new SigningKeyValidationTheoryData - { - TestId = "Valid_DelegateUsingConfigurationSet_ReturnsTrue", - ExpectedException = ExpectedException.NoExceptionExpected, - SecurityKey = KeyingMaterial.SymmetricSecurityKey2_256, - SecurityToken = new JwtSecurityToken(), - ValidationParameters = new TokenValidationParameters - { - ValidateIssuerSigningKey = true, - IssuerSigningKeyValidatorUsingConfiguration = (SecurityKey securityKey, SecurityToken token, TokenValidationParameters validationParameters, BaseConfiguration configuration) => true - }, - BaseConfiguration = new OpenIdConnectConfiguration(), + ValidationParameters = new ValidationParameters(), SigningKeyValidationResult = new SigningKeyValidationResult(KeyingMaterial.SymmetricSecurityKey2_256) }, new SigningKeyValidationTheoryData @@ -135,7 +63,7 @@ public static TheoryData SigningKeyValidationTes ExpectedException = ExpectedException.ArgumentNullException(substringExpected: "IDX10253:"), SecurityKey = null, SecurityToken = new JwtSecurityToken(), - ValidationParameters = new TokenValidationParameters { ValidateIssuerSigningKey = true }, + ValidationParameters = new ValidationParameters(), SigningKeyValidationResult = new SigningKeyValidationResult( null, // SecurityKey ValidationFailureType.NullArgument, @@ -146,11 +74,11 @@ public static TheoryData SigningKeyValidationTes }, new SigningKeyValidationTheoryData { - TestId = "Invalid_SecurityTokenIsNullAndValidateIssuerSigningKeyTrue", + TestId = "Invalid_SecurityTokenIsNull", ExpectedException = ExpectedException.ArgumentNullException(), SecurityKey = KeyingMaterial.SymmetricSecurityKey2_256, SecurityToken = null, - ValidationParameters = new TokenValidationParameters { ValidateIssuerSigningKey = true }, + ValidationParameters = new ValidationParameters (), SigningKeyValidationResult = new SigningKeyValidationResult( KeyingMaterial.SymmetricSecurityKey2_256, ValidationFailureType.NullArgument, @@ -184,7 +112,7 @@ public static TheoryData SigningKeyValidationTes ExpectedException = ExpectedException.SecurityTokenInvalidSigningKeyException(substringExpected: "IDX10249:"), SecurityKey = KeyingMaterial.ExpiredX509SecurityKey_Public, SecurityToken = new JwtSecurityToken(), - ValidationParameters = new TokenValidationParameters { ValidateIssuerSigningKey = true }, + ValidationParameters = new ValidationParameters (), SigningKeyValidationResult = new SigningKeyValidationResult( KeyingMaterial.ExpiredX509SecurityKey_Public, ValidationFailureType.SigningKeyValidationFailed, @@ -202,7 +130,7 @@ public static TheoryData SigningKeyValidationTes ExpectedException = ExpectedException.SecurityTokenInvalidSigningKeyException(substringExpected: "IDX10248:"), SecurityKey = KeyingMaterial.NotYetValidX509SecurityKey_Public, SecurityToken = new JwtSecurityToken(), - ValidationParameters = new TokenValidationParameters { ValidateIssuerSigningKey = true }, + ValidationParameters = new ValidationParameters (), SigningKeyValidationResult = new SigningKeyValidationResult( KeyingMaterial.NotYetValidX509SecurityKey_Public, ValidationFailureType.SigningKeyValidationFailed, @@ -216,11 +144,11 @@ public static TheoryData SigningKeyValidationTes }, new SigningKeyValidationTheoryData { - TestId = "Invalid_SecurityKeyIsNull_RequireSignedTokensIsTrue", + TestId = "Invalid_SecurityKeyIsNull", ExpectedException = ExpectedException.ArgumentNullException(substringExpected: "IDX10253:"), SecurityKey = null, SecurityToken = new JwtSecurityToken(), - ValidationParameters = new TokenValidationParameters { ValidateIssuerSigningKey = true, RequireSignedTokens = true }, + ValidationParameters = new ValidationParameters (), SigningKeyValidationResult = new SigningKeyValidationResult( null, ValidationFailureType.NullArgument, @@ -229,105 +157,18 @@ public static TheoryData SigningKeyValidationTes typeof(ArgumentNullException), new StackFrame(true))) }, - new SigningKeyValidationTheoryData - { - TestId = "Invalid_DelegateIsSet_ReturnsFalse", - ExpectedException = ExpectedException.SecurityTokenInvalidSigningKeyException(substringExpected: "IDX10232:"), - SecurityKey = KeyingMaterial.SymmetricSecurityKey2_256, - SecurityToken = new JwtSecurityToken(), - ValidationParameters = new TokenValidationParameters - { - ValidateIssuerSigningKey = true, - IssuerSigningKeyValidator = (SecurityKey securityKey, SecurityToken token, TokenValidationParameters validationParameters) => false - }, - SigningKeyValidationResult = new SigningKeyValidationResult( - KeyingMaterial.SymmetricSecurityKey2_256, - ValidationFailureType.SigningKeyValidationFailed, - new ExceptionDetail( - new MessageDetail( - LogMessages.IDX10232, - KeyingMaterial.SymmetricSecurityKey2_256), - typeof(SecurityTokenInvalidSigningKeyException), - new StackFrame(true))) - }, - new SigningKeyValidationTheoryData - { - TestId = "Invalid_DelegateUsingConfigurationSet_ReturnsFalse", - ExpectedException = ExpectedException.SecurityTokenInvalidSigningKeyException(substringExpected: "IDX10232:"), - SecurityKey = KeyingMaterial.SymmetricSecurityKey2_256, - SecurityToken = new JwtSecurityToken(), - ValidationParameters = new TokenValidationParameters - { - ValidateIssuerSigningKey = true, - IssuerSigningKeyValidatorUsingConfiguration = (SecurityKey securityKey, SecurityToken token, TokenValidationParameters validationParameters, BaseConfiguration configuration) => false - }, - BaseConfiguration = new OpenIdConnectConfiguration(), - SigningKeyValidationResult = new SigningKeyValidationResult( - KeyingMaterial.SymmetricSecurityKey2_256, - ValidationFailureType.SigningKeyValidationFailed, - new ExceptionDetail( - new MessageDetail( - LogMessages.IDX10232, - KeyingMaterial.SymmetricSecurityKey2_256), - typeof(SecurityTokenInvalidSigningKeyException), - new StackFrame(true))) - }, - new SigningKeyValidationTheoryData - { - TestId = "Invalid_DelegateIsSet_Throws", - ExpectedException = ExpectedException.SecurityTokenInvalidSigningKeyException(substringExpected: "IDX10232:", innerTypeExpected: typeof(SecurityTokenInvalidSigningKeyException)), - SecurityKey = KeyingMaterial.SymmetricSecurityKey2_256, - SecurityToken = new JwtSecurityToken(), - ValidationParameters = new TokenValidationParameters - { - ValidateIssuerSigningKey = true, - IssuerSigningKeyValidator = (SecurityKey securityKey, SecurityToken token, TokenValidationParameters validationParameters) => throw new SecurityTokenInvalidSigningKeyException() - }, - SigningKeyValidationResult = new SigningKeyValidationResult( - KeyingMaterial.SymmetricSecurityKey2_256, - ValidationFailureType.SigningKeyValidationFailed, - new ExceptionDetail( - new MessageDetail( - LogMessages.IDX10232, - KeyingMaterial.SymmetricSecurityKey2_256), - typeof(SecurityTokenInvalidSigningKeyException), - new StackFrame(true), - new SecurityTokenInvalidSigningKeyException())) - }, - new SigningKeyValidationTheoryData - { - TestId = "Invalid_DelegateUsingConfigurationSet_Throws", - ExpectedException = ExpectedException.SecurityTokenInvalidSigningKeyException(substringExpected: "IDX10232:", innerTypeExpected: typeof(SecurityTokenInvalidSigningKeyException)), - SecurityKey = KeyingMaterial.SymmetricSecurityKey2_256, - SecurityToken = new JwtSecurityToken(), - ValidationParameters = new TokenValidationParameters - { - ValidateIssuerSigningKey = true, - IssuerSigningKeyValidatorUsingConfiguration = (SecurityKey securityKey, SecurityToken token, TokenValidationParameters validationParameters, BaseConfiguration configuration) => throw new SecurityTokenInvalidSigningKeyException() - }, - BaseConfiguration = new OpenIdConnectConfiguration(), - SigningKeyValidationResult = new SigningKeyValidationResult( - KeyingMaterial.SymmetricSecurityKey2_256, - ValidationFailureType.SigningKeyValidationFailed, - new ExceptionDetail( - new MessageDetail( - LogMessages.IDX10232, - KeyingMaterial.SymmetricSecurityKey2_256), - typeof(SecurityTokenInvalidSigningKeyException), - new StackFrame(true), - new SecurityTokenInvalidSigningKeyException())) - }, - }; - } + + }; } } + } - public class SigningKeyValidationTheoryData: TheoryDataBase - { - public SecurityKey SecurityKey { get; set; } - public SecurityToken SecurityToken { get; set; } - public TokenValidationParameters ValidationParameters { get; set; } - public BaseConfiguration BaseConfiguration { get; set; } - internal SigningKeyValidationResult SigningKeyValidationResult { get; set; } - } + public class SigningKeyValidationTheoryData : TheoryDataBase + { + public SecurityKey SecurityKey { get; set; } + public SecurityToken SecurityToken { get; set; } + internal ValidationParameters ValidationParameters { get; set; } + public BaseConfiguration BaseConfiguration { get; set; } + internal SigningKeyValidationResult SigningKeyValidationResult { get; set; } } +} diff --git a/test/Microsoft.IdentityModel.Tokens.Tests/Validation/ValidationParametersTests.cs b/test/Microsoft.IdentityModel.Tokens.Tests/Validation/ValidationParametersTests.cs index 7d1a98de4f..603e7fb896 100644 --- a/test/Microsoft.IdentityModel.Tokens.Tests/Validation/ValidationParametersTests.cs +++ b/test/Microsoft.IdentityModel.Tokens.Tests/Validation/ValidationParametersTests.cs @@ -18,6 +18,7 @@ public void SetValidators_NullValue_ThrowsArgumentNullException() Assert.Throws(() => validationParameters.LifetimeValidator = null); Assert.Throws(() => validationParameters.TypeValidator = null); Assert.Throws(() => validationParameters.AudienceValidator = null); + Assert.Throws(() => validationParameters.IssuerSigningKeyValidator = null); } [Fact]