diff --git a/test/Microsoft.IdentityModel.JsonWebTokens.Tests/JsonWebTokenHandler.Extensibility.Algorithm.cs b/test/Microsoft.IdentityModel.JsonWebTokens.Tests/JsonWebTokenHandler.Extensibility.Algorithm.cs index fdfc48ed4a..7de840b3c3 100644 --- a/test/Microsoft.IdentityModel.JsonWebTokens.Tests/JsonWebTokenHandler.Extensibility.Algorithm.cs +++ b/test/Microsoft.IdentityModel.JsonWebTokens.Tests/JsonWebTokenHandler.Extensibility.Algorithm.cs @@ -1,14 +1,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -using System; -using System.Diagnostics; -using System.Threading; using System.Threading.Tasks; -using Microsoft.IdentityModel.JsonWebTokens.Tests; -using Microsoft.IdentityModel.Logging; -using Microsoft.IdentityModel.TestUtils; -using Microsoft.IdentityModel.Tokens; +using Microsoft.IdentityModel.TestUtils.TokenValidationExtensibility.Tests; using Xunit; #nullable enable @@ -16,318 +10,27 @@ namespace Microsoft.IdentityModel.JsonWebTokens.Extensibility.Tests { public partial class JsonWebTokenHandlerValidateTokenAsyncTests { - [Theory, MemberData(nameof(Algorithm_ExtensibilityTestCases), DisableDiscoveryEnumeration = true)] - public async Task ValidateTokenAsync_AlgorithmValidator_Extensibility(AlgorithmExtensibilityTheoryData theoryData) + [Theory, MemberData( + nameof(GenerateAlgorithmExtensibilityTestCases), + parameters: ["JWT", 1], + DisableDiscoveryEnumeration = true)] + public async Task ValidateTokenAsync_AlgorithmValidator_Extensibility( + AlgorithmExtensibilityTheoryData theoryData) { - var context = TestUtilities.WriteHeader($"{this}.{nameof(ValidateTokenAsync_AlgorithmValidator_Extensibility)}", theoryData); - context.IgnoreType = false; - for (int i = 0; i < theoryData.ExtraStackFrames; i++) - theoryData.ValidationError!.AddStackFrame(new StackFrame(false)); - - theoryData.ValidationParameters!.IssuerSigningKeys.Add(theoryData.SigningKey); - - try - { - ValidationResult validationResult = await theoryData.JsonWebTokenHandler.ValidateTokenAsync( - theoryData.JsonWebToken!, - theoryData.ValidationParameters!, - theoryData.CallContext, - CancellationToken.None); - - if (validationResult.IsValid) - { - // We expect the validation to fail, but it passed - context.AddDiff("ValidationResult is Valid."); - } - else - { - ValidationError validationError = validationResult.UnwrapError(); - - if (validationError is SignatureValidationError signatureValidationError && - signatureValidationError.InnerValidationError is not null) - { - IdentityComparer.AreValidationErrorsEqual( - signatureValidationError.InnerValidationError, - theoryData.ValidationError, - context); - } - else - { - IdentityComparer.AreValidationErrorsEqual( - validationError, - theoryData.ValidationError, - context); - } - - var exception = validationError.GetException(); - theoryData.ExpectedException.ProcessException(exception, context); - // Process the inner exception since invalid algorithm exceptions are wrapped inside - // invalid signature exceptions - if (theoryData.ExpectedInnerException is not null) - theoryData.ExpectedInnerException.ProcessException(exception.InnerException, context); - } - } - catch (Exception ex) - { - // We expect the validation to fail, but it threw an exception - context.AddDiff($"ValidateTokenAsync threw exception: {ex}"); - } - - TestUtilities.AssertFailIfErrors(context); + await ExtensibilityTesting.ValidateTokenAsync_Extensibility( + theoryData, + this, + nameof(ValidateTokenAsync_AlgorithmValidator_Extensibility)); } - public static TheoryData Algorithm_ExtensibilityTestCases + public static TheoryData GenerateAlgorithmExtensibilityTestCases( + string tokenHandlerType, + int extraStackFrames) { - get - { - var theoryData = new TheoryData(); - CallContext callContext = new CallContext(); - var utcNow = DateTime.UtcNow; - var utcPlusOneHour = utcNow + TimeSpan.FromHours(1); - - #region return CustomAlgorithmValidationError - // Test cases where delegate is overridden and return a CustomAlgorithmValidationError - // CustomAlgorithmValidationError : AlgorithmValidationError, ExceptionType: SecurityTokenInvalidAlgorithmException - theoryData.Add(new AlgorithmExtensibilityTheoryData( - "CustomAlgorithmValidatorDelegate", - utcNow, - CustomAlgorithmValidationDelegates.CustomAlgorithmValidatorDelegate, - extraStackFrames: 1) - { - ExpectedException = new ExpectedException( - typeof(SecurityTokenInvalidSignatureException), - "IDX10518:", - typeof(SecurityTokenInvalidAlgorithmException)), - ExpectedInnerException = new ExpectedException( - typeof(SecurityTokenInvalidAlgorithmException), - nameof(CustomAlgorithmValidationDelegates.CustomAlgorithmValidatorDelegate)), - ValidationError = new CustomAlgorithmValidationError( - new MessageDetail( - nameof(CustomAlgorithmValidationDelegates.CustomAlgorithmValidatorDelegate), null), - ValidationFailureType.AlgorithmValidationFailed, - typeof(SecurityTokenInvalidAlgorithmException), - new StackFrame("CustomAlgorithmValidationDelegates.cs", 160), - "algorithm") - }); - - // CustomAlgorithmValidationError : AlgorithmValidationError, ExceptionType: CustomSecurityTokenInvalidAlgorithmException : SecurityTokenInvalidAlgorithmException - theoryData.Add(new AlgorithmExtensibilityTheoryData( - "CustomAlgorithmValidatorCustomExceptionDelegate", - utcNow, - CustomAlgorithmValidationDelegates.CustomAlgorithmValidatorCustomExceptionDelegate, - extraStackFrames: 1) - { - ExpectedException = new ExpectedException( - typeof(SecurityTokenInvalidSignatureException), - "IDX10518:", - typeof(CustomSecurityTokenInvalidAlgorithmException)), - ExpectedInnerException = new ExpectedException( - typeof(CustomSecurityTokenInvalidAlgorithmException), - nameof(CustomAlgorithmValidationDelegates.CustomAlgorithmValidatorCustomExceptionDelegate)), - ValidationError = new CustomAlgorithmValidationError( - new MessageDetail( - nameof(CustomAlgorithmValidationDelegates.CustomAlgorithmValidatorCustomExceptionDelegate), null), - ValidationFailureType.AlgorithmValidationFailed, - typeof(CustomSecurityTokenInvalidAlgorithmException), - new StackFrame("CustomAlgorithmValidationDelegates.cs", 175), - "algorithm"), - }); - - // CustomAlgorithmValidationError : AlgorithmValidationError, ExceptionType: NotSupportedException : SystemException - theoryData.Add(new AlgorithmExtensibilityTheoryData( - "CustomAlgorithmValidatorUnknownExceptionDelegate", - utcNow, - CustomAlgorithmValidationDelegates.CustomAlgorithmValidatorUnknownExceptionDelegate, - extraStackFrames: 1) - { - // CustomAlgorithmValidationError does not handle the exception type 'NotSupportedException' - ExpectedException = new ExpectedException( - typeof(SecurityTokenInvalidSignatureException), - "IDX10518:", - typeof(SecurityTokenException)), - ExpectedInnerException = ExpectedException.SecurityTokenException( - LogHelper.FormatInvariant( - Tokens.LogMessages.IDX10002, // "IDX10002: Unknown exception type returned. Type: '{0}'. Message: '{1}'."; - typeof(NotSupportedException), - nameof(CustomAlgorithmValidationDelegates.CustomAlgorithmValidatorUnknownExceptionDelegate))), - ValidationError = new CustomAlgorithmValidationError( - new MessageDetail( - nameof(CustomAlgorithmValidationDelegates.CustomAlgorithmValidatorUnknownExceptionDelegate), null), - ValidationFailureType.AlgorithmValidationFailed, - typeof(NotSupportedException), - new StackFrame("CustomAlgorithmValidationDelegates.cs", 205), - "algorithm"), - }); - - // CustomAlgorithmValidationError : AlgorithmValidationError, ExceptionType: NotSupportedException : SystemException, ValidationFailureType: CustomAudienceValidationFailureType - theoryData.Add(new AlgorithmExtensibilityTheoryData( - "CustomAlgorithmValidatorCustomExceptionCustomFailureTypeDelegate", - utcNow, - CustomAlgorithmValidationDelegates.CustomAlgorithmValidatorCustomExceptionCustomFailureTypeDelegate, - extraStackFrames: 1) - { - ExpectedException = new ExpectedException( - typeof(SecurityTokenInvalidSignatureException), - "IDX10518:", - typeof(CustomSecurityTokenInvalidAlgorithmException)), - ExpectedInnerException = new ExpectedException( - typeof(CustomSecurityTokenInvalidAlgorithmException), - nameof(CustomAlgorithmValidationDelegates.CustomAlgorithmValidatorCustomExceptionCustomFailureTypeDelegate)), - ValidationError = new CustomAlgorithmValidationError( - new MessageDetail( - nameof(CustomAlgorithmValidationDelegates.CustomAlgorithmValidatorCustomExceptionCustomFailureTypeDelegate), null), - CustomAlgorithmValidationError.CustomAlgorithmValidationFailureType, - typeof(CustomSecurityTokenInvalidAlgorithmException), - new StackFrame("CustomAlgorithmValidationDelegates.cs", 190), - "algorithm"), - }); - #endregion - - #region return AlgorithmValidationError - // Test cases where delegate is overridden and return an AlgorithmValidationError - // AlgorithmValidationError : ValidationError, ExceptionType: SecurityTokenInvalidAlgorithmException - theoryData.Add(new AlgorithmExtensibilityTheoryData( - "AlgorithmValidatorDelegate", - utcNow, - CustomAlgorithmValidationDelegates.AlgorithmValidatorDelegate, - extraStackFrames: 1) - { - ExpectedException = new ExpectedException( - typeof(SecurityTokenInvalidSignatureException), - "IDX10518:", - typeof(SecurityTokenInvalidAlgorithmException)), - ExpectedInnerException = new ExpectedException( - typeof(SecurityTokenInvalidAlgorithmException), - nameof(CustomAlgorithmValidationDelegates.AlgorithmValidatorDelegate)), - ValidationError = new AlgorithmValidationError( - new MessageDetail( - nameof(CustomAlgorithmValidationDelegates.AlgorithmValidatorDelegate), null), - ValidationFailureType.AlgorithmValidationFailed, - typeof(SecurityTokenInvalidAlgorithmException), - new StackFrame("CustomAlgorithmValidationDelegates.cs", 235), - "algorithm") - }); - - // AlgorithmValidationError : ValidationError, ExceptionType: CustomSecurityTokenInvalidAlgorithmException : SecurityTokenInvalidAlgorithmException - theoryData.Add(new AlgorithmExtensibilityTheoryData( - "AlgorithmValidatorCustomAlgorithmExceptionTypeDelegate", - utcNow, - CustomAlgorithmValidationDelegates.AlgorithmValidatorCustomAlgorithmExceptionTypeDelegate, - extraStackFrames: 1) - { - // AlgorithmValidationError does not handle the exception type 'CustomSecurityTokenInvalidAlgorithmException' - ExpectedException = new ExpectedException( - typeof(SecurityTokenInvalidSignatureException), - "IDX10518:", - typeof(SecurityTokenException)), - ExpectedInnerException = ExpectedException.SecurityTokenException( - LogHelper.FormatInvariant( - Tokens.LogMessages.IDX10002, // "IDX10002: Unknown exception type returned. Type: '{0}'. Message: '{1}'."; - typeof(CustomSecurityTokenInvalidAlgorithmException), - nameof(CustomAlgorithmValidationDelegates.AlgorithmValidatorCustomAlgorithmExceptionTypeDelegate))), - ValidationError = new AlgorithmValidationError( - new MessageDetail( - nameof(CustomAlgorithmValidationDelegates.AlgorithmValidatorCustomAlgorithmExceptionTypeDelegate), null), - ValidationFailureType.AlgorithmValidationFailed, - typeof(CustomSecurityTokenInvalidAlgorithmException), - new StackFrame("CustomAlgorithmValidationDelegates.cs", 259), - "algorithm") - }); - - // AlgorithmValidationError : ValidationError, ExceptionType: CustomSecurityTokenException : SystemException - theoryData.Add(new AlgorithmExtensibilityTheoryData( - "AlgorithmValidatorCustomExceptionTypeDelegate", - utcNow, - CustomAlgorithmValidationDelegates.AlgorithmValidatorCustomExceptionTypeDelegate, - extraStackFrames: 1) - { - // AlgorithmValidationError does not handle the exception type 'CustomSecurityTokenException' - ExpectedException = new ExpectedException( - typeof(SecurityTokenInvalidSignatureException), - "IDX10518:", - typeof(SecurityTokenException)), - ExpectedInnerException = ExpectedException.SecurityTokenException( - LogHelper.FormatInvariant( - Tokens.LogMessages.IDX10002, // "IDX10002: Unknown exception type returned. Type: '{0}'. Message: '{1}'."; - typeof(CustomSecurityTokenException), - nameof(CustomAlgorithmValidationDelegates.AlgorithmValidatorCustomExceptionTypeDelegate))), - ValidationError = new AlgorithmValidationError( - new MessageDetail( - nameof(CustomAlgorithmValidationDelegates.AlgorithmValidatorCustomExceptionTypeDelegate), null), - ValidationFailureType.AlgorithmValidationFailed, - typeof(CustomSecurityTokenException), - new StackFrame("CustomAlgorithmValidationDelegates.cs", 274), - "algorithm") - }); - - // SignatureValidationError : ValidationError, ExceptionType: SecurityTokenInvalidSignatureException, inner: CustomSecurityTokenInvalidAlgorithmException - theoryData.Add(new AlgorithmExtensibilityTheoryData( - "AlgorithmValidatorThrows", - utcNow, - CustomAlgorithmValidationDelegates.AlgorithmValidatorThrows, - extraStackFrames: 2) - { - ExpectedException = new ExpectedException( - typeof(SecurityTokenInvalidSignatureException), - "IDX10273:", - typeof(CustomSecurityTokenInvalidAlgorithmException)), - ExpectedInnerException = new ExpectedException( - typeof(CustomSecurityTokenInvalidAlgorithmException), - nameof(CustomAlgorithmValidationDelegates.AlgorithmValidatorThrows)), - ValidationError = new SignatureValidationError( - new MessageDetail( - string.Format(Tokens.LogMessages.IDX10273), null), - ValidationFailureType.AlgorithmValidatorThrew, - typeof(SecurityTokenInvalidSignatureException), - new StackFrame("JsonWebTokenHandler.ValidateSignature.cs", 250), - null, // no inner validation error - new CustomSecurityTokenInvalidAlgorithmException(nameof(CustomAlgorithmValidationDelegates.AlgorithmValidatorThrows), null) - ) - }); - #endregion - - return theoryData; - } - } - - public class AlgorithmExtensibilityTheoryData : ValidateTokenAsyncBaseTheoryData - { - internal AlgorithmExtensibilityTheoryData(string testId, DateTime utcNow, AlgorithmValidationDelegate algorithmValidator, int extraStackFrames) : base(testId) - { - // The token is never read by the custom delegtes, so we create a dummy token - JsonWebToken = JsonWebTokenHandler.ReadJsonWebToken(JsonWebTokenHandler.CreateToken(new SecurityTokenDescriptor() - { - SigningCredentials = Default.SymmetricSigningCredentials, - })); - - ValidationParameters = new ValidationParameters - { - // We leave the default signature validator to call the custom algorithm validator - AlgorithmValidator = algorithmValidator, - AudienceValidator = SkipValidationDelegates.SkipAudienceValidation, - IssuerValidatorAsync = SkipValidationDelegates.SkipIssuerValidation, - IssuerSigningKeyValidator = SkipValidationDelegates.SkipIssuerSigningKeyValidation, - LifetimeValidator = SkipValidationDelegates.SkipLifetimeValidation, - TokenReplayValidator = SkipValidationDelegates.SkipTokenReplayValidation, - TokenTypeValidator = SkipValidationDelegates.SkipTokenTypeValidation, - }; - - ExtraStackFrames = extraStackFrames; - } - - public JsonWebToken JsonWebToken { get; } - - public JsonWebTokenHandler JsonWebTokenHandler { get; } = new JsonWebTokenHandler(); - - public bool IsValid { get; set; } - - internal ValidationError? ValidationError { get; set; } - - public ExpectedException? ExpectedInnerException { get; set; } - - internal int ExtraStackFrames { get; } - - public SecurityKey SigningKey { get; set; } = Default.SymmetricSigningKey; + return ExtensibilityTesting.GenerateAlgorithmExtensibilityTestCases( + tokenHandlerType, + extraStackFrames, + "JsonWebTokenHandler.ValidateSignature.cs"); } } } diff --git a/test/Microsoft.IdentityModel.JsonWebTokens.Tests/JsonWebTokenHandler.Extensibility.IssuerSigningKey.cs b/test/Microsoft.IdentityModel.JsonWebTokens.Tests/JsonWebTokenHandler.Extensibility.IssuerSigningKey.cs index 3b2bd111c6..fb24e4a51f 100644 --- a/test/Microsoft.IdentityModel.JsonWebTokens.Tests/JsonWebTokenHandler.Extensibility.IssuerSigningKey.cs +++ b/test/Microsoft.IdentityModel.JsonWebTokens.Tests/JsonWebTokenHandler.Extensibility.IssuerSigningKey.cs @@ -1,14 +1,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -using System; -using System.Diagnostics; -using System.Threading; using System.Threading.Tasks; -using Microsoft.IdentityModel.JsonWebTokens.Tests; -using Microsoft.IdentityModel.Logging; -using Microsoft.IdentityModel.TestUtils; -using Microsoft.IdentityModel.Tokens; +using Microsoft.IdentityModel.TestUtils.TokenValidationExtensibility.Tests; using Xunit; #nullable enable @@ -16,268 +10,27 @@ namespace Microsoft.IdentityModel.JsonWebTokens.Extensibility.Tests { public partial class JsonWebTokenHandlerValidateTokenAsyncTests { - [Theory, MemberData(nameof(IssuerSigningKey_ExtensibilityTestCases), DisableDiscoveryEnumeration = true)] - public async Task ValidateTokenAsync_IssuerSigningKeyValidator_Extensibility(IssuerSigningKeyExtensibilityTheoryData theoryData) + [Theory, MemberData( + nameof(GenerateIssuerSigningKeyExtensibilityTestCases), + parameters: ["JWT", 2], + DisableDiscoveryEnumeration = true)] + public async Task ValidateTokenAsync_IssuerSigningKeyValidator_Extensibility( + IssuerSigningKeyExtensibilityTheoryData theoryData) { - var context = TestUtilities.WriteHeader($"{this}.{nameof(ValidateTokenAsync_IssuerSigningKeyValidator_Extensibility)}", theoryData); - context.IgnoreType = false; - for (int i = 0; i < theoryData.ExtraStackFrames; i++) - theoryData.IssuerSigningKeyValidationError!.AddStackFrame(new StackFrame(false)); - - try - { - ValidationResult validationResult = await theoryData.JsonWebTokenHandler.ValidateTokenAsync( - theoryData.JsonWebToken!, - theoryData.ValidationParameters!, - theoryData.CallContext, - CancellationToken.None); - - if (validationResult.IsValid) - { - context.AddDiff("validationResult.IsValid is true, expected false"); - } - else - { - ValidationError validationError = validationResult.UnwrapError(); - IdentityComparer.AreValidationErrorsEqual(validationError, theoryData.IssuerSigningKeyValidationError, context); - theoryData.ExpectedException.ProcessException(validationError.GetException(), context); - } - } - catch (Exception ex) - { - theoryData.ExpectedException.ProcessException(ex, context); - } - - TestUtilities.AssertFailIfErrors(context); - } - - public static TheoryData IssuerSigningKey_ExtensibilityTestCases - { - get - { - var theoryData = new TheoryData(); - CallContext callContext = new CallContext(); - var utcNow = DateTime.UtcNow; - var utcPlusOneHour = utcNow + TimeSpan.FromHours(1); - - #region return CustomIssuerSigningKeyValidationError - // Test cases where delegate is overridden and return a CustomIssuerSigningKeyValidationError - // CustomIssuerSigningKeyValidationError : IssuerSigningKeyValidationError, ExceptionType: SecurityTokenInvalidIssuerSigningKeyException - theoryData.Add(new IssuerSigningKeyExtensibilityTheoryData( - "CustomIssuerSigningKeyValidatorDelegate", - utcNow, - CustomIssuerSigningKeyValidationDelegates.CustomIssuerSigningKeyValidatorDelegate, - extraStackFrames: 2) - { - ExpectedException = new ExpectedException( - typeof(SecurityTokenInvalidSigningKeyException), - nameof(CustomIssuerSigningKeyValidationDelegates.CustomIssuerSigningKeyValidatorDelegate)), - IssuerSigningKeyValidationError = new CustomIssuerSigningKeyValidationError( - new MessageDetail( - nameof(CustomIssuerSigningKeyValidationDelegates.CustomIssuerSigningKeyValidatorDelegate), null), - ValidationFailureType.SigningKeyValidationFailed, - typeof(SecurityTokenInvalidSigningKeyException), - new StackFrame("CustomIssuerSigningKeyValidationDelegates.cs", 160), - null) - }); - - // CustomIssuerSigningKeyValidationError : IssuerSigningKeyValidationError, ExceptionType: CustomSecurityTokenInvalidIssuerSigningKeyException : SecurityTokenInvalidIssuerSigningKeyException - theoryData.Add(new IssuerSigningKeyExtensibilityTheoryData( - "CustomIssuerSigningKeyValidatorCustomExceptionDelegate", - utcNow, - CustomIssuerSigningKeyValidationDelegates.CustomIssuerSigningKeyValidatorCustomExceptionDelegate, - extraStackFrames: 2) - { - ExpectedException = new ExpectedException( - typeof(CustomSecurityTokenInvalidSigningKeyException), - nameof(CustomIssuerSigningKeyValidationDelegates.CustomIssuerSigningKeyValidatorCustomExceptionDelegate)), - IssuerSigningKeyValidationError = new CustomIssuerSigningKeyValidationError( - new MessageDetail( - nameof(CustomIssuerSigningKeyValidationDelegates.CustomIssuerSigningKeyValidatorCustomExceptionDelegate), null), - ValidationFailureType.SigningKeyValidationFailed, - typeof(CustomSecurityTokenInvalidSigningKeyException), - new StackFrame("CustomIssuerSigningKeyValidationDelegates.cs", 175), - null), - }); - - // CustomIssuerSigningKeyValidationError : IssuerSigningKeyValidationError, ExceptionType: NotSupportedException : SystemException - theoryData.Add(new IssuerSigningKeyExtensibilityTheoryData( - "CustomIssuerSigningKeyValidatorUnknownExceptionDelegate", - utcNow, - CustomIssuerSigningKeyValidationDelegates.CustomIssuerSigningKeyValidatorUnknownExceptionDelegate, - extraStackFrames: 2) - { - // CustomIssuerSigningKeyValidationError does not handle the exception type 'NotSupportedException' - ExpectedException = ExpectedException.SecurityTokenException( - LogHelper.FormatInvariant( - Tokens.LogMessages.IDX10002, // "IDX10002: Unknown exception type returned. Type: '{0}'. Message: '{1}'."; - typeof(NotSupportedException), - nameof(CustomIssuerSigningKeyValidationDelegates.CustomIssuerSigningKeyValidatorUnknownExceptionDelegate))), - IssuerSigningKeyValidationError = new CustomIssuerSigningKeyValidationError( - new MessageDetail( - nameof(CustomIssuerSigningKeyValidationDelegates.CustomIssuerSigningKeyValidatorUnknownExceptionDelegate), null), - ValidationFailureType.SigningKeyValidationFailed, - typeof(NotSupportedException), - new StackFrame("CustomIssuerSigningKeyValidationDelegates.cs", 205), - null), - }); - - // CustomIssuerSigningKeyValidationError : IssuerSigningKeyValidationError, ExceptionType: NotSupportedException : SystemException, ValidationFailureType: CustomAudienceValidationFailureType - theoryData.Add(new IssuerSigningKeyExtensibilityTheoryData( - "CustomIssuerSigningKeyValidatorCustomExceptionCustomFailureTypeDelegate", - utcNow, - CustomIssuerSigningKeyValidationDelegates.CustomIssuerSigningKeyValidatorCustomExceptionCustomFailureTypeDelegate, - extraStackFrames: 2) - { - ExpectedException = new ExpectedException( - typeof(CustomSecurityTokenInvalidSigningKeyException), - nameof(CustomIssuerSigningKeyValidationDelegates.CustomIssuerSigningKeyValidatorCustomExceptionCustomFailureTypeDelegate)), - IssuerSigningKeyValidationError = new CustomIssuerSigningKeyValidationError( - new MessageDetail( - nameof(CustomIssuerSigningKeyValidationDelegates.CustomIssuerSigningKeyValidatorCustomExceptionCustomFailureTypeDelegate), null), - CustomIssuerSigningKeyValidationError.CustomIssuerSigningKeyValidationFailureType, - typeof(CustomSecurityTokenInvalidSigningKeyException), - new StackFrame("CustomIssuerSigningKeyValidationDelegates.cs", 190), - null), - }); - #endregion - - #region return IssuerSigningKeyValidationError - // Test cases where delegate is overridden and return an IssuerSigningKeyValidationError - // IssuerSigningKeyValidationError : ValidationError, ExceptionType: SecurityTokenInvalidIssuerSigningKeyException - theoryData.Add(new IssuerSigningKeyExtensibilityTheoryData( - "IssuerSigningKeyValidatorDelegate", - utcNow, - CustomIssuerSigningKeyValidationDelegates.IssuerSigningKeyValidatorDelegate, - extraStackFrames: 2) - { - ExpectedException = new ExpectedException( - typeof(SecurityTokenInvalidSigningKeyException), - nameof(CustomIssuerSigningKeyValidationDelegates.IssuerSigningKeyValidatorDelegate)), - IssuerSigningKeyValidationError = new IssuerSigningKeyValidationError( - new MessageDetail( - nameof(CustomIssuerSigningKeyValidationDelegates.IssuerSigningKeyValidatorDelegate), null), - ValidationFailureType.SigningKeyValidationFailed, - typeof(SecurityTokenInvalidSigningKeyException), - new StackFrame("CustomIssuerSigningKeyValidationDelegates.cs", 235), - null) - }); - - // IssuerSigningKeyValidationError : ValidationError, ExceptionType: CustomSecurityTokenInvalidIssuerSigningKeyException : SecurityTokenInvalidIssuerSigningKeyException - theoryData.Add(new IssuerSigningKeyExtensibilityTheoryData( - "IssuerSigningKeyValidatorCustomIssuerSigningKeyExceptionTypeDelegate", - utcNow, - CustomIssuerSigningKeyValidationDelegates.IssuerSigningKeyValidatorCustomIssuerSigningKeyExceptionTypeDelegate, - extraStackFrames: 2) - { - // IssuerSigningKeyValidationError does not handle the exception type 'CustomSecurityTokenInvalidIssuerSigningKeyException' - ExpectedException = ExpectedException.SecurityTokenException( - LogHelper.FormatInvariant( - Tokens.LogMessages.IDX10002, // "IDX10002: Unknown exception type returned. Type: '{0}'. Message: '{1}'."; - typeof(CustomSecurityTokenInvalidSigningKeyException), - nameof(CustomIssuerSigningKeyValidationDelegates.IssuerSigningKeyValidatorCustomIssuerSigningKeyExceptionTypeDelegate))), - IssuerSigningKeyValidationError = new IssuerSigningKeyValidationError( - new MessageDetail( - nameof(CustomIssuerSigningKeyValidationDelegates.IssuerSigningKeyValidatorCustomIssuerSigningKeyExceptionTypeDelegate), null), - ValidationFailureType.SigningKeyValidationFailed, - typeof(CustomSecurityTokenInvalidSigningKeyException), - new StackFrame("CustomIssuerSigningKeyValidationDelegates.cs", 259), - null) - }); - - // IssuerSigningKeyValidationError : ValidationError, ExceptionType: CustomSecurityTokenException : SystemException - theoryData.Add(new IssuerSigningKeyExtensibilityTheoryData( - "IssuerSigningKeyValidatorCustomExceptionTypeDelegate", - utcNow, - CustomIssuerSigningKeyValidationDelegates.IssuerSigningKeyValidatorCustomExceptionTypeDelegate, - extraStackFrames: 2) - { - // IssuerSigningKeyValidationError does not handle the exception type 'CustomSecurityTokenException' - ExpectedException = ExpectedException.SecurityTokenException( - LogHelper.FormatInvariant( - Tokens.LogMessages.IDX10002, // "IDX10002: Unknown exception type returned. Type: '{0}'. Message: '{1}'."; - typeof(CustomSecurityTokenException), - nameof(CustomIssuerSigningKeyValidationDelegates.IssuerSigningKeyValidatorCustomExceptionTypeDelegate))), - IssuerSigningKeyValidationError = new IssuerSigningKeyValidationError( - new MessageDetail( - nameof(CustomIssuerSigningKeyValidationDelegates.IssuerSigningKeyValidatorCustomExceptionTypeDelegate), null), - ValidationFailureType.SigningKeyValidationFailed, - typeof(CustomSecurityTokenException), - new StackFrame("CustomIssuerSigningKeyValidationDelegates.cs", 274), - null) - }); - - // IssuerSigningKeyValidationError : ValidationError, ExceptionType: SecurityTokenInvalidIssuerSigningKeyException, inner: CustomSecurityTokenInvalidIssuerSigningKeyException - theoryData.Add(new IssuerSigningKeyExtensibilityTheoryData( - "IssuerSigningKeyValidatorThrows", - utcNow, - CustomIssuerSigningKeyValidationDelegates.IssuerSigningKeyValidatorThrows, - extraStackFrames: 1) - { - ExpectedException = new ExpectedException( - typeof(SecurityTokenInvalidSigningKeyException), - string.Format(Tokens.LogMessages.IDX10274), - typeof(CustomSecurityTokenInvalidSigningKeyException)), - IssuerSigningKeyValidationError = new IssuerSigningKeyValidationError( - new MessageDetail( - string.Format(Tokens.LogMessages.IDX10274), null), - ValidationFailureType.IssuerSigningKeyValidatorThrew, - typeof(SecurityTokenInvalidSigningKeyException), - new StackFrame("JsonWebTokenHandler.ValidateToken.Internal.cs", 250), - null, - new SecurityTokenInvalidSigningKeyException(nameof(CustomIssuerSigningKeyValidationDelegates.IssuerSigningKeyValidatorThrows)) - ) - }); - #endregion - - return theoryData; - } + await ExtensibilityTesting.ValidateTokenAsync_Extensibility( + theoryData, + this, + nameof(ValidateTokenAsync_IssuerSigningKeyValidator_Extensibility)); } - public class IssuerSigningKeyExtensibilityTheoryData : ValidateTokenAsyncBaseTheoryData + public static TheoryData GenerateIssuerSigningKeyExtensibilityTestCases( + string tokenHandlerType, + int extraStackFrames) { - internal IssuerSigningKeyExtensibilityTheoryData(string testId, DateTime utcNow, IssuerSigningKeyValidationDelegate issuerSigningKeyValidator, int extraStackFrames) : base(testId) - { - JsonWebToken = JsonWebTokenHandler.ReadJsonWebToken( - JsonWebTokenHandler.CreateToken( - new SecurityTokenDescriptor() - { - IssuedAt = utcNow, - NotBefore = utcNow, - Expires = utcNow + TimeSpan.FromHours(1), - })); - - ValidationParameters = new ValidationParameters - { - AlgorithmValidator = SkipValidationDelegates.SkipAlgorithmValidation, - AudienceValidator = SkipValidationDelegates.SkipAudienceValidation, - IssuerValidatorAsync = SkipValidationDelegates.SkipIssuerValidation, - IssuerSigningKeyValidator = issuerSigningKeyValidator, - LifetimeValidator = SkipValidationDelegates.SkipLifetimeValidation, - SignatureValidator = (SecurityToken token, ValidationParameters validationParameters, BaseConfiguration? configuration, CallContext callContext) => - { - token.SigningKey = SigningKey; - - return SigningKey; - }, - TokenReplayValidator = SkipValidationDelegates.SkipTokenReplayValidation, - TokenTypeValidator = SkipValidationDelegates.SkipTokenTypeValidation - }; - - ExtraStackFrames = extraStackFrames; - } - - public JsonWebToken JsonWebToken { get; } - - public JsonWebTokenHandler JsonWebTokenHandler { get; } = new JsonWebTokenHandler(); - - public bool IsValid { get; set; } - - public SecurityKey SigningKey { get; set; } = KeyingMaterial.DefaultX509SigningCreds_2048_RsaSha2_Sha2.Key; - - internal IssuerSigningKeyValidationError? IssuerSigningKeyValidationError { get; set; } - - internal int ExtraStackFrames { get; } + return ExtensibilityTesting.GenerateIssuerSigningKeyExtensibilityTestCases( + tokenHandlerType, + extraStackFrames, + "JsonWebTokenHandler.ValidateToken.Internal.cs"); } } } diff --git a/test/Microsoft.IdentityModel.JsonWebTokens.Tests/JsonWebTokenHandler.Extensibility.Signature.cs b/test/Microsoft.IdentityModel.JsonWebTokens.Tests/JsonWebTokenHandler.Extensibility.Signature.cs index ac497daa72..8c6c8a75d0 100644 --- a/test/Microsoft.IdentityModel.JsonWebTokens.Tests/JsonWebTokenHandler.Extensibility.Signature.cs +++ b/test/Microsoft.IdentityModel.JsonWebTokens.Tests/JsonWebTokenHandler.Extensibility.Signature.cs @@ -1,15 +1,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -using System; -using System.Diagnostics; -using System.Threading; using System.Threading.Tasks; -using Microsoft.IdentityModel.JsonWebTokens.Tests; -using Microsoft.IdentityModel.Logging; -using Microsoft.IdentityModel.TestUtils; -using Microsoft.IdentityModel.Tokens; -using Microsoft.IdentityModel.Tokens.Json.Tests; +using Microsoft.IdentityModel.TestUtils.TokenValidationExtensibility.Tests; using Xunit; #nullable enable @@ -17,249 +10,27 @@ namespace Microsoft.IdentityModel.JsonWebTokens.Extensibility.Tests { public partial class JsonWebTokenHandlerValidateTokenAsyncTests { - [Theory, MemberData(nameof(Signature_ExtensibilityTestCases), DisableDiscoveryEnumeration = true)] - public async Task ValidateTokenAsync_SignatureValidator_Extensibility(SignatureExtensibilityTheoryData theoryData) + [Theory, MemberData( + nameof(GenerateSignatureExtensibilityTestCases), + parameters: ["JWT", 3], + DisableDiscoveryEnumeration = true)] + public async Task ValidateTokenAsync_SignatureValidator_Extensibility( + SignatureExtensibilityTheoryData theoryData) { - var context = TestUtilities.WriteHeader($"{this}.{nameof(ValidateTokenAsync_SignatureValidator_Extensibility)}", theoryData); - context.IgnoreType = false; - for (int i = 0; i < theoryData.ExtraStackFrames; i++) - theoryData.SignatureValidationError!.AddStackFrame(new StackFrame(false)); - - try - { - ValidationResult validationResult = await theoryData.JsonWebTokenHandler.ValidateTokenAsync( - theoryData.JsonWebToken!, - theoryData.ValidationParameters!, - theoryData.CallContext, - CancellationToken.None); - - if (validationResult.IsValid) - { - // We expect the validation to fail, but it passed - context.AddDiff("ValidationResult is Valid."); - } - else - { - ValidationError validationError = validationResult.UnwrapError(); - IdentityComparer.AreValidationErrorsEqual(validationError, theoryData.SignatureValidationError, context); - theoryData.ExpectedException.ProcessException(validationError.GetException(), context); - } - } - catch (Exception ex) - { - theoryData.ExpectedException.ProcessException(ex, context); - } - - TestUtilities.AssertFailIfErrors(context); - } - - public static TheoryData Signature_ExtensibilityTestCases - { - get - { - var theoryData = new TheoryData(); - CallContext callContext = new CallContext(); - var utcNow = DateTime.UtcNow; - var utcPlusOneHour = utcNow + TimeSpan.FromHours(1); - - #region return CustomSignatureValidationError - // Test cases where delegate is overridden and return a CustomSignatureValidationError - // CustomSignatureValidationError : SignatureValidationError, ExceptionType: SecurityTokenInvalidSignatureException - theoryData.Add(new SignatureExtensibilityTheoryData( - "CustomSignatureValidatorDelegate", - utcNow, - CustomSignatureValidationDelegates.CustomSignatureValidatorDelegate, - extraStackFrames: 3) - { - ExpectedException = new ExpectedException( - typeof(SecurityTokenInvalidSignatureException), - nameof(CustomSignatureValidationDelegates.CustomSignatureValidatorDelegate)), - SignatureValidationError = new CustomSignatureValidationError( - new MessageDetail( - nameof(CustomSignatureValidationDelegates.CustomSignatureValidatorDelegate), null), - ValidationFailureType.SignatureValidationFailed, - typeof(SecurityTokenInvalidSignatureException), - new StackFrame("CustomSignatureValidationDelegates.cs", 160)) - }); - - // CustomSignatureValidationError : SignatureValidationError, ExceptionType: CustomSecurityTokenInvalidSignatureException : SecurityTokenInvalidSignatureException - theoryData.Add(new SignatureExtensibilityTheoryData( - "CustomSignatureValidatorCustomExceptionDelegate", - utcNow, - CustomSignatureValidationDelegates.CustomSignatureValidatorCustomExceptionDelegate, - extraStackFrames: 3) - { - ExpectedException = new ExpectedException( - typeof(CustomSecurityTokenInvalidSignatureException), - nameof(CustomSignatureValidationDelegates.CustomSignatureValidatorCustomExceptionDelegate)), - SignatureValidationError = new CustomSignatureValidationError( - new MessageDetail( - nameof(CustomSignatureValidationDelegates.CustomSignatureValidatorCustomExceptionDelegate), null), - ValidationFailureType.SignatureValidationFailed, - typeof(CustomSecurityTokenInvalidSignatureException), - new StackFrame("CustomSignatureValidationDelegates.cs", 175)), - }); - - // CustomSignatureValidationError : SignatureValidationError, ExceptionType: NotSupportedException : SystemException - theoryData.Add(new SignatureExtensibilityTheoryData( - "CustomSignatureValidatorUnknownExceptionDelegate", - utcNow, - CustomSignatureValidationDelegates.CustomSignatureValidatorUnknownExceptionDelegate, - extraStackFrames: 3) - { - // CustomSignatureValidationError does not handle the exception type 'NotSupportedException' - ExpectedException = ExpectedException.SecurityTokenException( - LogHelper.FormatInvariant( - Tokens.LogMessages.IDX10002, // "IDX10002: Unknown exception type returned. Type: '{0}'. Message: '{1}'."; - typeof(NotSupportedException), - nameof(CustomSignatureValidationDelegates.CustomSignatureValidatorUnknownExceptionDelegate))), - SignatureValidationError = new CustomSignatureValidationError( - new MessageDetail( - nameof(CustomSignatureValidationDelegates.CustomSignatureValidatorUnknownExceptionDelegate), null), - ValidationFailureType.SignatureValidationFailed, - typeof(NotSupportedException), - new StackFrame("CustomSignatureValidationDelegates.cs", 205)), - }); - - // CustomSignatureValidationError : SignatureValidationError, ExceptionType: NotSupportedException : SystemException, ValidationFailureType: CustomAudienceValidationFailureType - theoryData.Add(new SignatureExtensibilityTheoryData( - "CustomSignatureValidatorCustomExceptionCustomFailureTypeDelegate", - utcNow, - CustomSignatureValidationDelegates.CustomSignatureValidatorCustomExceptionCustomFailureTypeDelegate, - extraStackFrames: 3) - { - ExpectedException = new ExpectedException( - typeof(CustomSecurityTokenInvalidSignatureException), - nameof(CustomSignatureValidationDelegates.CustomSignatureValidatorCustomExceptionCustomFailureTypeDelegate)), - SignatureValidationError = new CustomSignatureValidationError( - new MessageDetail( - nameof(CustomSignatureValidationDelegates.CustomSignatureValidatorCustomExceptionCustomFailureTypeDelegate), null), - CustomSignatureValidationError.CustomSignatureValidationFailureType, - typeof(CustomSecurityTokenInvalidSignatureException), - new StackFrame("CustomSignatureValidationDelegates.cs", 190)), - }); - #endregion - - #region return SignatureValidationError - // Test cases where delegate is overridden and return an SignatureValidationError - // SignatureValidationError : ValidationError, ExceptionType: SecurityTokenInvalidSignatureException - theoryData.Add(new SignatureExtensibilityTheoryData( - "SignatureValidatorDelegate", - utcNow, - CustomSignatureValidationDelegates.SignatureValidatorDelegate, - extraStackFrames: 3) - { - ExpectedException = new ExpectedException( - typeof(SecurityTokenInvalidSignatureException), - nameof(CustomSignatureValidationDelegates.SignatureValidatorDelegate)), - SignatureValidationError = new SignatureValidationError( - new MessageDetail( - nameof(CustomSignatureValidationDelegates.SignatureValidatorDelegate), null), - ValidationFailureType.SignatureValidationFailed, - typeof(SecurityTokenInvalidSignatureException), - new StackFrame("CustomSignatureValidationDelegates.cs", 235)) - }); - - // SignatureValidationError : ValidationError, ExceptionType: CustomSecurityTokenInvalidSignatureException : SecurityTokenInvalidSignatureException - theoryData.Add(new SignatureExtensibilityTheoryData( - "SignatureValidatorCustomSignatureExceptionTypeDelegate", - utcNow, - CustomSignatureValidationDelegates.SignatureValidatorCustomSignatureExceptionTypeDelegate, - extraStackFrames: 3) - { - // SignatureValidationError does not handle the exception type 'CustomSecurityTokenInvalidSignatureException' - ExpectedException = ExpectedException.SecurityTokenException( - LogHelper.FormatInvariant( - Tokens.LogMessages.IDX10002, // "IDX10002: Unknown exception type returned. Type: '{0}'. Message: '{1}'."; - typeof(CustomSecurityTokenInvalidSignatureException), - nameof(CustomSignatureValidationDelegates.SignatureValidatorCustomSignatureExceptionTypeDelegate))), - SignatureValidationError = new SignatureValidationError( - new MessageDetail( - nameof(CustomSignatureValidationDelegates.SignatureValidatorCustomSignatureExceptionTypeDelegate), null), - ValidationFailureType.SignatureValidationFailed, - typeof(CustomSecurityTokenInvalidSignatureException), - new StackFrame("CustomSignatureValidationDelegates.cs", 259)) - }); - - // SignatureValidationError : ValidationError, ExceptionType: CustomSecurityTokenException : SystemException - theoryData.Add(new SignatureExtensibilityTheoryData( - "SignatureValidatorCustomExceptionTypeDelegate", - utcNow, - CustomSignatureValidationDelegates.SignatureValidatorCustomExceptionTypeDelegate, - extraStackFrames: 3) - { - // SignatureValidationError does not handle the exception type 'CustomSecurityTokenException' - ExpectedException = ExpectedException.SecurityTokenException( - LogHelper.FormatInvariant( - Tokens.LogMessages.IDX10002, // "IDX10002: Unknown exception type returned. Type: '{0}'. Message: '{1}'."; - typeof(CustomSecurityTokenException), - nameof(CustomSignatureValidationDelegates.SignatureValidatorCustomExceptionTypeDelegate))), - SignatureValidationError = new SignatureValidationError( - new MessageDetail( - nameof(CustomSignatureValidationDelegates.SignatureValidatorCustomExceptionTypeDelegate), null), - ValidationFailureType.SignatureValidationFailed, - typeof(CustomSecurityTokenException), - new StackFrame("CustomSignatureValidationDelegates.cs", 274)) - }); - - // SignatureValidationError : ValidationError, ExceptionType: SecurityTokenInvalidSignatureException, inner: CustomSecurityTokenInvalidSignatureException - theoryData.Add(new SignatureExtensibilityTheoryData( - "SignatureValidatorThrows", - utcNow, - CustomSignatureValidationDelegates.SignatureValidatorThrows, - extraStackFrames: 2) - { - ExpectedException = new ExpectedException( - typeof(SecurityTokenInvalidSignatureException), - string.Format(Tokens.LogMessages.IDX10272), - typeof(CustomSecurityTokenInvalidSignatureException)), - SignatureValidationError = new SignatureValidationError( - new MessageDetail( - string.Format(Tokens.LogMessages.IDX10272), null), - ValidationFailureType.SignatureValidatorThrew, - typeof(SecurityTokenInvalidSignatureException), - new StackFrame("JsonWebTokenHandler.ValidateSignature.cs", 250), - null, // no inner validation error - new SecurityTokenInvalidSignatureException(nameof(CustomSignatureValidationDelegates.SignatureValidatorThrows)) - ) - }); - #endregion - - return theoryData; - } + await ExtensibilityTesting.ValidateTokenAsync_Extensibility( + theoryData, + this, + nameof(ValidateTokenAsync_SignatureValidator_Extensibility)); } - public class SignatureExtensibilityTheoryData : ValidateTokenAsyncBaseTheoryData + public static TheoryData GenerateSignatureExtensibilityTestCases( + string tokenHandlerType, + int extraStackFrames) { - internal SignatureExtensibilityTheoryData(string testId, DateTime utcNow, SignatureValidationDelegate signatureValidator, int extraStackFrames) : base(testId) - { - // The token is never read by the custom delegtes, so we create a dummy token - JsonWebToken = JsonUtilities.CreateUnsignedJsonWebToken("iss", "issuer"); - - ValidationParameters = new ValidationParameters - { - AlgorithmValidator = SkipValidationDelegates.SkipAlgorithmValidation, - AudienceValidator = SkipValidationDelegates.SkipAudienceValidation, - IssuerValidatorAsync = SkipValidationDelegates.SkipIssuerValidation, - IssuerSigningKeyValidator = SkipValidationDelegates.SkipIssuerSigningKeyValidation, - LifetimeValidator = SkipValidationDelegates.SkipLifetimeValidation, - SignatureValidator = signatureValidator, - TokenReplayValidator = SkipValidationDelegates.SkipTokenReplayValidation, - TokenTypeValidator = SkipValidationDelegates.SkipTokenTypeValidation - }; - - ExtraStackFrames = extraStackFrames; - } - - public JsonWebToken JsonWebToken { get; } - - public JsonWebTokenHandler JsonWebTokenHandler { get; } = new JsonWebTokenHandler(); - - public bool IsValid { get; set; } - - internal SignatureValidationError? SignatureValidationError { get; set; } - - internal int ExtraStackFrames { get; } + return ExtensibilityTesting.GenerateSignatureExtensibilityTestCases( + tokenHandlerType, + extraStackFrames, + "JsonWebTokenHandler.ValidateSignature.cs"); } } } diff --git a/test/Microsoft.IdentityModel.JsonWebTokens.Tests/JsonWebTokenHandler.Extensibility.TokenReplay.cs b/test/Microsoft.IdentityModel.JsonWebTokens.Tests/JsonWebTokenHandler.Extensibility.TokenReplay.cs index 3f96081d85..7e17dd4ca8 100644 --- a/test/Microsoft.IdentityModel.JsonWebTokens.Tests/JsonWebTokenHandler.Extensibility.TokenReplay.cs +++ b/test/Microsoft.IdentityModel.JsonWebTokens.Tests/JsonWebTokenHandler.Extensibility.TokenReplay.cs @@ -1,14 +1,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -using System; -using System.Diagnostics; -using System.Threading; using System.Threading.Tasks; -using Microsoft.IdentityModel.JsonWebTokens.Tests; -using Microsoft.IdentityModel.Logging; -using Microsoft.IdentityModel.TestUtils; -using Microsoft.IdentityModel.Tokens; +using Microsoft.IdentityModel.TestUtils.TokenValidationExtensibility.Tests; using Xunit; #nullable enable @@ -16,261 +10,27 @@ namespace Microsoft.IdentityModel.JsonWebTokens.Extensibility.Tests { public partial class JsonWebTokenHandlerValidateTokenAsyncTests { - [Theory, MemberData(nameof(TokenReplay_ExtensibilityTestCases), DisableDiscoveryEnumeration = true)] - public async Task ValidateTokenAsync_TokenReplayValidator_Extensibility(TokenReplayExtensibilityTheoryData theoryData) + [Theory, MemberData( + nameof(GenerateTokenReplayExtensibilityTestCases), + parameters: ["JWT", 2], + DisableDiscoveryEnumeration = true)] + public async Task ValidateTokenAsync_TokenReplayValidator_Extensibility( + TokenReplayExtensibilityTheoryData theoryData) { - var context = TestUtilities.WriteHeader($"{this}.{nameof(ValidateTokenAsync_TokenReplayValidator_Extensibility)}", theoryData); - context.IgnoreType = false; - for (int i = 0; i < theoryData.ExtraStackFrames; i++) - theoryData.TokenReplayValidationError!.AddStackFrame(new StackFrame(false)); - - try - { - ValidationResult validationResult = await theoryData.JsonWebTokenHandler.ValidateTokenAsync( - theoryData.JsonWebToken!, - theoryData.ValidationParameters!, - theoryData.CallContext, - CancellationToken.None); - - if (validationResult.IsValid) - { - context.Diffs.Add("validationResult.IsValid is true, expected false"); - } - else - { - ValidationError validationError = validationResult.UnwrapError(); - IdentityComparer.AreValidationErrorsEqual(validationError, theoryData.TokenReplayValidationError, context); - theoryData.ExpectedException.ProcessException(validationError.GetException(), context); - } - } - catch (Exception ex) - { - theoryData.ExpectedException.ProcessException(ex, context); - } - - TestUtilities.AssertFailIfErrors(context); - } - - public static TheoryData TokenReplay_ExtensibilityTestCases - { - get - { - var theoryData = new TheoryData(); - CallContext callContext = new CallContext(); - var utcNow = DateTime.UtcNow; - var expirationTime = utcNow + TimeSpan.FromHours(1); - - #region return CustomTokenReplayValidationError - // Test cases where delegate is overridden and return a CustomTokenReplayValidationError - // CustomTokenReplayValidationError : TokenReplayValidationError, ExceptionType: SecurityTokenReplayDetectedException - theoryData.Add(new TokenReplayExtensibilityTheoryData( - "CustomTokenReplayValidationDelegate", - utcNow, - CustomTokenReplayValidationDelegates.CustomTokenReplayValidationDelegate, - extraStackFrames: 2) - { - ExpectedException = new ExpectedException( - typeof(SecurityTokenReplayDetectedException), - nameof(CustomTokenReplayValidationDelegates.CustomTokenReplayValidationDelegate)), - TokenReplayValidationError = new CustomTokenReplayValidationError( - new MessageDetail( - nameof(CustomTokenReplayValidationDelegates.CustomTokenReplayValidationDelegate), null), - ValidationFailureType.TokenReplayValidationFailed, - typeof(SecurityTokenReplayDetectedException), - new StackFrame("CustomTokenReplayValidationDelegates.cs", 160), - expirationTime) - }); - - // CustomTokenReplayValidationError : TokenReplayValidationError, ExceptionType: CustomSecurityTokenReplayDetectedException : SecurityTokenReplayDetectedException - theoryData.Add(new TokenReplayExtensibilityTheoryData( - "CustomTokenReplayValidatorCustomExceptionDelegate", - utcNow, - CustomTokenReplayValidationDelegates.CustomTokenReplayValidatorCustomExceptionDelegate, - extraStackFrames: 2) - { - ExpectedException = new ExpectedException( - typeof(CustomSecurityTokenReplayDetectedException), - nameof(CustomTokenReplayValidationDelegates.CustomTokenReplayValidatorCustomExceptionDelegate)), - TokenReplayValidationError = new CustomTokenReplayValidationError( - new MessageDetail( - nameof(CustomTokenReplayValidationDelegates.CustomTokenReplayValidatorCustomExceptionDelegate), null), - ValidationFailureType.TokenReplayValidationFailed, - typeof(CustomSecurityTokenReplayDetectedException), - new StackFrame("CustomTokenReplayValidationDelegates.cs", 175), - expirationTime), - }); - - // CustomTokenReplayValidationError : TokenReplayValidationError, ExceptionType: NotSupportedException : SystemException - theoryData.Add(new TokenReplayExtensibilityTheoryData( - "CustomTokenReplayValidatorUnknownExceptionDelegate", - utcNow, - CustomTokenReplayValidationDelegates.CustomTokenReplayValidatorUnknownExceptionDelegate, - extraStackFrames: 2) - { - // CustomTokenReplayValidationError does not handle the exception type 'NotSupportedException' - ExpectedException = ExpectedException.SecurityTokenException( - LogHelper.FormatInvariant( - Tokens.LogMessages.IDX10002, // "IDX10002: Unknown exception type returned. Type: '{0}'. Message: '{1}'."; - typeof(NotSupportedException), - nameof(CustomTokenReplayValidationDelegates.CustomTokenReplayValidatorUnknownExceptionDelegate))), - TokenReplayValidationError = new CustomTokenReplayValidationError( - new MessageDetail( - nameof(CustomTokenReplayValidationDelegates.CustomTokenReplayValidatorUnknownExceptionDelegate), null), - ValidationFailureType.TokenReplayValidationFailed, - typeof(NotSupportedException), - new StackFrame("CustomTokenReplayValidationDelegates.cs", 205), - expirationTime), - }); - - // CustomTokenReplayValidationError : TokenReplayValidationError, ExceptionType: NotSupportedException : SystemException, ValidationFailureType: CustomAudienceValidationFailureType - theoryData.Add(new TokenReplayExtensibilityTheoryData( - "CustomTokenReplayValidatorCustomExceptionCustomFailureTypeDelegate", - utcNow, - CustomTokenReplayValidationDelegates.CustomTokenReplayValidatorCustomExceptionCustomFailureTypeDelegate, - extraStackFrames: 2) - { - ExpectedException = new ExpectedException( - typeof(CustomSecurityTokenReplayDetectedException), - nameof(CustomTokenReplayValidationDelegates.CustomTokenReplayValidatorCustomExceptionCustomFailureTypeDelegate)), - TokenReplayValidationError = new CustomTokenReplayValidationError( - new MessageDetail( - nameof(CustomTokenReplayValidationDelegates.CustomTokenReplayValidatorCustomExceptionCustomFailureTypeDelegate), null), - CustomTokenReplayValidationError.CustomTokenReplayValidationFailureType, - typeof(CustomSecurityTokenReplayDetectedException), - new StackFrame("CustomTokenReplayValidationDelegates.cs", 190), - expirationTime), - }); - #endregion - - #region return TokenReplayValidationError - // Test cases where delegate is overridden and return an TokenReplayValidationError - // TokenReplayValidationError : ValidationError, ExceptionType: SecurityTokenReplayDetectedException - theoryData.Add(new TokenReplayExtensibilityTheoryData( - "TokenReplayValidationDelegate", - utcNow, - CustomTokenReplayValidationDelegates.TokenReplayValidationDelegate, - extraStackFrames: 2) - { - ExpectedException = new ExpectedException( - typeof(SecurityTokenReplayDetectedException), - nameof(CustomTokenReplayValidationDelegates.TokenReplayValidationDelegate)), - TokenReplayValidationError = new TokenReplayValidationError( - new MessageDetail( - nameof(CustomTokenReplayValidationDelegates.TokenReplayValidationDelegate), null), - ValidationFailureType.TokenReplayValidationFailed, - typeof(SecurityTokenReplayDetectedException), - new StackFrame("CustomTokenReplayValidationDelegates.cs", 235), - expirationTime) - }); - - // TokenReplayValidationError : ValidationError, ExceptionType: CustomSecurityTokenReplayDetectedException : SecurityTokenReplayDetectedException - theoryData.Add(new TokenReplayExtensibilityTheoryData( - "TokenReplayValidatorCustomTokenReplayDetectedExceptionTypeDelegate", - utcNow, - CustomTokenReplayValidationDelegates.TokenReplayValidatorCustomTokenReplayDetectedExceptionTypeDelegate, - extraStackFrames: 2) - { - // TokenReplayValidationError does not handle the exception type 'CustomSecurityTokenReplayDetectedException' - ExpectedException = ExpectedException.SecurityTokenException( - LogHelper.FormatInvariant( - Tokens.LogMessages.IDX10002, // "IDX10002: Unknown exception type returned. Type: '{0}'. Message: '{1}'."; - typeof(CustomSecurityTokenReplayDetectedException), - nameof(CustomTokenReplayValidationDelegates.TokenReplayValidatorCustomTokenReplayDetectedExceptionTypeDelegate))), - TokenReplayValidationError = new TokenReplayValidationError( - new MessageDetail( - nameof(CustomTokenReplayValidationDelegates.TokenReplayValidatorCustomTokenReplayDetectedExceptionTypeDelegate), null), - ValidationFailureType.TokenReplayValidationFailed, - typeof(CustomSecurityTokenReplayDetectedException), - new StackFrame("CustomTokenReplayValidationDelegates.cs", 259), - expirationTime) - }); - - // TokenReplayValidationError : ValidationError, ExceptionType: CustomSecurityTokenException : SystemException - theoryData.Add(new TokenReplayExtensibilityTheoryData( - "TokenReplayValidatorCustomExceptionTypeDelegate", - utcNow, - CustomTokenReplayValidationDelegates.TokenReplayValidatorCustomExceptionTypeDelegate, - extraStackFrames: 2) - { - // TokenReplayValidationError does not handle the exception type 'CustomSecurityTokenException' - ExpectedException = ExpectedException.SecurityTokenException( - LogHelper.FormatInvariant( - Tokens.LogMessages.IDX10002, // "IDX10002: Unknown exception type returned. Type: '{0}'. Message: '{1}'."; - typeof(CustomSecurityTokenException), - nameof(CustomTokenReplayValidationDelegates.TokenReplayValidatorCustomExceptionTypeDelegate))), - TokenReplayValidationError = new TokenReplayValidationError( - new MessageDetail( - nameof(CustomTokenReplayValidationDelegates.TokenReplayValidatorCustomExceptionTypeDelegate), null), - ValidationFailureType.TokenReplayValidationFailed, - typeof(CustomSecurityTokenException), - new StackFrame("CustomTokenReplayValidationDelegates.cs", 274), - expirationTime) - }); - - // TokenReplayValidationError : ValidationError, ExceptionType: SecurityTokenReplayDetectedException, inner: CustomSecurityTokenReplayDetectedException - theoryData.Add(new TokenReplayExtensibilityTheoryData( - "TokenReplayValidatorThrows", - utcNow, - CustomTokenReplayValidationDelegates.TokenReplayValidatorThrows, - extraStackFrames: 1) - { - ExpectedException = new ExpectedException( - typeof(SecurityTokenReplayDetectedException), - string.Format(Tokens.LogMessages.IDX10276), - typeof(CustomSecurityTokenReplayDetectedException)), - TokenReplayValidationError = new TokenReplayValidationError( - new MessageDetail( - string.Format(Tokens.LogMessages.IDX10276), null), - ValidationFailureType.TokenReplayValidatorThrew, - typeof(SecurityTokenReplayDetectedException), - new StackFrame("JsonWebTokenHandler.ValidateToken.Internal.cs", 250), - expirationTime, - new SecurityTokenReplayDetectedException(nameof(CustomTokenReplayValidationDelegates.TokenReplayValidatorThrows)) - ) - }); - #endregion - - return theoryData; - } + await ExtensibilityTesting.ValidateTokenAsync_Extensibility( + theoryData, + this, + nameof(ValidateTokenAsync_TokenReplayValidator_Extensibility)); } - public class TokenReplayExtensibilityTheoryData : ValidateTokenAsyncBaseTheoryData + public static TheoryData GenerateTokenReplayExtensibilityTestCases( + string tokenHandlerType, + int extraStackFrames) { - internal TokenReplayExtensibilityTheoryData(string testId, DateTime utcNow, TokenReplayValidationDelegate tokenReplayValidator, int extraStackFrames) : base(testId) - { - JsonWebToken = JsonWebTokenHandler.ReadJsonWebToken( - JsonWebTokenHandler.CreateToken( - new SecurityTokenDescriptor() - { - IssuedAt = utcNow, - NotBefore = utcNow, - Expires = utcNow + TimeSpan.FromHours(1), - })); - - ValidationParameters = new ValidationParameters - { - AlgorithmValidator = SkipValidationDelegates.SkipAlgorithmValidation, - AudienceValidator = SkipValidationDelegates.SkipAudienceValidation, - IssuerValidatorAsync = SkipValidationDelegates.SkipIssuerValidation, - IssuerSigningKeyValidator = SkipValidationDelegates.SkipIssuerSigningKeyValidation, - LifetimeValidator = SkipValidationDelegates.SkipLifetimeValidation, - SignatureValidator = SkipValidationDelegates.SkipSignatureValidation, - TokenReplayValidator = tokenReplayValidator, - TokenTypeValidator = SkipValidationDelegates.SkipTokenTypeValidation - }; - - ExtraStackFrames = extraStackFrames; - } - - public JsonWebToken JsonWebToken { get; } - - public JsonWebTokenHandler JsonWebTokenHandler { get; } = new JsonWebTokenHandler(); - - public bool IsValid { get; set; } - - internal TokenReplayValidationError? TokenReplayValidationError { get; set; } - - internal int ExtraStackFrames { get; } + return ExtensibilityTesting.GenerateTokenReplayExtensibilityTestCases( + tokenHandlerType, + extraStackFrames, + "JsonWebTokenHandler.ValidateToken.Internal.cs"); } } } diff --git a/test/Microsoft.IdentityModel.JsonWebTokens.Tests/JsonWebTokenHandler.Extensibility.TokenType.cs b/test/Microsoft.IdentityModel.JsonWebTokens.Tests/JsonWebTokenHandler.Extensibility.TokenType.cs index 08bcd74b40..ecc7f63439 100644 --- a/test/Microsoft.IdentityModel.JsonWebTokens.Tests/JsonWebTokenHandler.Extensibility.TokenType.cs +++ b/test/Microsoft.IdentityModel.JsonWebTokens.Tests/JsonWebTokenHandler.Extensibility.TokenType.cs @@ -1,15 +1,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -using System; -using System.Diagnostics; -using System.Threading; using System.Threading.Tasks; -using Microsoft.IdentityModel.JsonWebTokens.Tests; -using Microsoft.IdentityModel.Logging; -using Microsoft.IdentityModel.TestUtils; -using Microsoft.IdentityModel.Tokens; -using Microsoft.IdentityModel.Tokens.Json.Tests; +using Microsoft.IdentityModel.TestUtils.TokenValidationExtensibility.Tests; using Xunit; #nullable enable @@ -17,246 +10,27 @@ namespace Microsoft.IdentityModel.JsonWebTokens.Extensibility.Tests { public partial class JsonWebTokenHandlerValidateTokenAsyncTests { - [Theory, MemberData(nameof(TokenType_ExtensibilityTestCases), DisableDiscoveryEnumeration = true)] - public async Task ValidateTokenAsync_TokenTypeValidator_Extensibility(TokenTypeExtensibilityTheoryData theoryData) + [Theory, MemberData( + nameof(GenerateTokenTypeExtensibilityTestCases), + parameters: ["JWT", 2], + DisableDiscoveryEnumeration = true)] + public async Task ValidateTokenAsync_TokenTypeValidator_Extensibility( + TokenTypeExtensibilityTheoryData theoryData) { - var context = TestUtilities.WriteHeader($"{this}.{nameof(ValidateTokenAsync_TokenTypeValidator_Extensibility)}", theoryData); - context.IgnoreType = false; - for (int i = 0; i < theoryData.ExtraStackFrames; i++) - theoryData.TokenTypeValidationError!.AddStackFrame(new StackFrame(false)); - - try - { - ValidationResult validationResult = await theoryData.JsonWebTokenHandler.ValidateTokenAsync( - theoryData.JsonWebToken!, - theoryData.ValidationParameters!, - theoryData.CallContext, - CancellationToken.None); - - if (validationResult.IsValid) - { - context.Diffs.Add("validationResult.IsValid is true, expected false"); - } - else - { - ValidationError validationError = validationResult.UnwrapError(); - IdentityComparer.AreValidationErrorsEqual(validationError, theoryData.TokenTypeValidationError, context); - theoryData.ExpectedException.ProcessException(validationError.GetException(), context); - } - } - catch (Exception ex) - { - theoryData.ExpectedException.ProcessException(ex, context); - } - - TestUtilities.AssertFailIfErrors(context); + await ExtensibilityTesting.ValidateTokenAsync_Extensibility( + theoryData, + this, + nameof(ValidateTokenAsync_TokenTypeValidator_Extensibility)); } - public static TheoryData TokenType_ExtensibilityTestCases + public static TheoryData GenerateTokenTypeExtensibilityTestCases( + string tokenHandlerType, + int extraStackFrames) { - get - { - var theoryData = new TheoryData(); - CallContext callContext = new CallContext(); - - #region return CustomTokenTypeValidationError - // Test cases where delegate is overridden and return a CustomTokenTypeValidationError - // CustomTokenTypeValidationError : TokenTypeValidationError, ExceptionType: SecurityTokenInvalidTypeException - theoryData.Add(new TokenTypeExtensibilityTheoryData( - "CustomTokenTypeValidatorDelegate", - CustomTokenTypeValidationDelegates.CustomTokenTypeValidatorDelegate, - extraStackFrames: 2) - { - ExpectedException = new ExpectedException( - typeof(SecurityTokenInvalidTypeException), - nameof(CustomTokenTypeValidationDelegates.CustomTokenTypeValidatorDelegate)), - TokenTypeValidationError = new CustomTokenTypeValidationError( - new MessageDetail( - nameof(CustomTokenTypeValidationDelegates.CustomTokenTypeValidatorDelegate), null), - ValidationFailureType.TokenTypeValidationFailed, - typeof(SecurityTokenInvalidTypeException), - new StackFrame("CustomTokenTypeValidationDelegates.cs", 160), - "JWT") - }); - - // CustomTokenTypeValidationError : TokenTypeValidationError, ExceptionType: CustomSecurityTokenInvalidTypeException : SecurityTokenInvalidTypeException - theoryData.Add(new TokenTypeExtensibilityTheoryData( - "CustomTokenTypeValidatorCustomExceptionDelegate", - CustomTokenTypeValidationDelegates.CustomTokenTypeValidatorCustomExceptionDelegate, - extraStackFrames: 2) - { - ExpectedException = new ExpectedException( - typeof(CustomSecurityTokenInvalidTypeException), - nameof(CustomTokenTypeValidationDelegates.CustomTokenTypeValidatorCustomExceptionDelegate)), - TokenTypeValidationError = new CustomTokenTypeValidationError( - new MessageDetail( - nameof(CustomTokenTypeValidationDelegates.CustomTokenTypeValidatorCustomExceptionDelegate), null), - ValidationFailureType.TokenTypeValidationFailed, - typeof(CustomSecurityTokenInvalidTypeException), - new StackFrame("CustomTokenTypeValidationDelegates.cs", 175), - "JWT") - }); - - // CustomTokenTypeValidationError : TokenTypeValidationError, ExceptionType: NotSupportedException : SystemException - theoryData.Add(new TokenTypeExtensibilityTheoryData( - "CustomTokenTypeValidatorUnknownExceptionDelegate", - CustomTokenTypeValidationDelegates.CustomTokenTypeValidatorUnknownExceptionDelegate, - extraStackFrames: 2) - { - // CustomTokenTypeValidationError does not handle the exception type 'NotSupportedException' - ExpectedException = ExpectedException.SecurityTokenException( - LogHelper.FormatInvariant( - Tokens.LogMessages.IDX10002, // "IDX10002: Unknown exception type returned. Type: '{0}'. Message: '{1}'."; - typeof(NotSupportedException), - nameof(CustomTokenTypeValidationDelegates.CustomTokenTypeValidatorUnknownExceptionDelegate))), - TokenTypeValidationError = new CustomTokenTypeValidationError( - new MessageDetail( - nameof(CustomTokenTypeValidationDelegates.CustomTokenTypeValidatorUnknownExceptionDelegate), null), - ValidationFailureType.TokenTypeValidationFailed, - typeof(NotSupportedException), - new StackFrame("CustomTokenTypeValidationDelegates.cs", 205), - "JWT") - }); - - // CustomTokenTypeValidationError : TokenTypeValidationError, ExceptionType: NotSupportedException : SystemException, ValidationFailureType: CustomAudienceValidationFailureType - theoryData.Add(new TokenTypeExtensibilityTheoryData( - "CustomTokenTypeValidatorCustomExceptionCustomFailureTypeDelegate", - CustomTokenTypeValidationDelegates.CustomTokenTypeValidatorCustomExceptionCustomFailureTypeDelegate, - extraStackFrames: 2) - { - ExpectedException = new ExpectedException( - typeof(CustomSecurityTokenInvalidTypeException), - nameof(CustomTokenTypeValidationDelegates.CustomTokenTypeValidatorCustomExceptionCustomFailureTypeDelegate)), - TokenTypeValidationError = new CustomTokenTypeValidationError( - new MessageDetail( - nameof(CustomTokenTypeValidationDelegates.CustomTokenTypeValidatorCustomExceptionCustomFailureTypeDelegate), null), - CustomTokenTypeValidationError.CustomTokenTypeValidationFailureType, - typeof(CustomSecurityTokenInvalidTypeException), - new StackFrame("CustomTokenTypeValidationDelegates.cs", 190), - "JWT"), - }); - #endregion - - #region return TokenTypeValidationError - // Test cases where delegate is overridden and return an TokenTypeValidationError - // TokenTypeValidationError : ValidationError, ExceptionType: SecurityTokenInvalidTypeException - theoryData.Add(new TokenTypeExtensibilityTheoryData( - "TokenTypeValidatorDelegate", - CustomTokenTypeValidationDelegates.TokenTypeValidatorDelegate, - extraStackFrames: 2) - { - ExpectedException = new ExpectedException( - typeof(SecurityTokenInvalidTypeException), - nameof(CustomTokenTypeValidationDelegates.TokenTypeValidatorDelegate)), - TokenTypeValidationError = new TokenTypeValidationError( - new MessageDetail( - nameof(CustomTokenTypeValidationDelegates.TokenTypeValidatorDelegate), null), - ValidationFailureType.TokenTypeValidationFailed, - typeof(SecurityTokenInvalidTypeException), - new StackFrame("CustomTokenTypeValidationDelegates.cs", 235), - "JWT") - }); - - // TokenTypeValidationError : ValidationError, ExceptionType: CustomSecurityTokenInvalidTypeException : SecurityTokenInvalidTypeException - theoryData.Add(new TokenTypeExtensibilityTheoryData( - "TokenTypeValidatorCustomTokenTypeExceptionTypeDelegate", - CustomTokenTypeValidationDelegates.TokenTypeValidatorCustomTokenTypeExceptionTypeDelegate, - extraStackFrames: 2) - { - // TokenTypeValidationError does not handle the exception type 'CustomSecurityTokenInvalidTypeException' - ExpectedException = ExpectedException.SecurityTokenException( - LogHelper.FormatInvariant( - Tokens.LogMessages.IDX10002, // "IDX10002: Unknown exception type returned. Type: '{0}'. Message: '{1}'."; - typeof(CustomSecurityTokenInvalidTypeException), - nameof(CustomTokenTypeValidationDelegates.TokenTypeValidatorCustomTokenTypeExceptionTypeDelegate))), - TokenTypeValidationError = new TokenTypeValidationError( - new MessageDetail( - nameof(CustomTokenTypeValidationDelegates.TokenTypeValidatorCustomTokenTypeExceptionTypeDelegate), null), - ValidationFailureType.TokenTypeValidationFailed, - typeof(CustomSecurityTokenInvalidTypeException), - new StackFrame("CustomTokenTypeValidationDelegates.cs", 259), - "JWT") - }); - - // TokenTypeValidationError : ValidationError, ExceptionType: CustomSecurityTokenException : SystemException - theoryData.Add(new TokenTypeExtensibilityTheoryData( - "TokenTypeValidatorCustomExceptionTypeDelegate", - CustomTokenTypeValidationDelegates.TokenTypeValidatorCustomExceptionTypeDelegate, - extraStackFrames: 2) - { - // TokenTypeValidationError does not handle the exception type 'CustomSecurityTokenException' - ExpectedException = ExpectedException.SecurityTokenException( - LogHelper.FormatInvariant( - Tokens.LogMessages.IDX10002, // "IDX10002: Unknown exception type returned. Type: '{0}'. Message: '{1}'."; - typeof(CustomSecurityTokenException), - nameof(CustomTokenTypeValidationDelegates.TokenTypeValidatorCustomExceptionTypeDelegate))), - TokenTypeValidationError = new TokenTypeValidationError( - new MessageDetail( - nameof(CustomTokenTypeValidationDelegates.TokenTypeValidatorCustomExceptionTypeDelegate), null), - ValidationFailureType.TokenTypeValidationFailed, - typeof(CustomSecurityTokenException), - new StackFrame("CustomTokenTypeValidationDelegates.cs", 274), - "JWT") - }); - - // TokenTypeValidationError : ValidationError, ExceptionType: SecurityTokenInvalidTypeException, inner: CustomSecurityTokenInvalidTypeException - theoryData.Add(new TokenTypeExtensibilityTheoryData( - "TokenTypeValidatorThrows", - CustomTokenTypeValidationDelegates.TokenTypeValidatorThrows, - extraStackFrames: 1) - { - ExpectedException = new ExpectedException( - typeof(SecurityTokenInvalidTypeException), - string.Format(Tokens.LogMessages.IDX10275), - typeof(CustomSecurityTokenInvalidTypeException)), - TokenTypeValidationError = new TokenTypeValidationError( - new MessageDetail( - string.Format(Tokens.LogMessages.IDX10275), null), - ValidationFailureType.TokenTypeValidatorThrew, - typeof(SecurityTokenInvalidTypeException), - new StackFrame("JsonWebTokenHandler.ValidateToken.Internal.cs", 250), - "JWT", - new SecurityTokenInvalidTypeException(nameof(CustomTokenTypeValidationDelegates.TokenTypeValidatorThrows)) - ) - }); - #endregion - - return theoryData; - } - } - - public class TokenTypeExtensibilityTheoryData : ValidateTokenAsyncBaseTheoryData - { - internal TokenTypeExtensibilityTheoryData(string testId, TokenTypeValidationDelegate tokenTypeValidator, int extraStackFrames) : base(testId) - { - JsonWebToken = JsonUtilities.CreateUnsignedJsonWebToken("iss", "issuer"); - - ValidationParameters = new ValidationParameters - { - AlgorithmValidator = SkipValidationDelegates.SkipAlgorithmValidation, - AudienceValidator = SkipValidationDelegates.SkipAudienceValidation, - IssuerValidatorAsync = SkipValidationDelegates.SkipIssuerValidation, - IssuerSigningKeyValidator = SkipValidationDelegates.SkipIssuerSigningKeyValidation, - LifetimeValidator = SkipValidationDelegates.SkipLifetimeValidation, - SignatureValidator = SkipValidationDelegates.SkipSignatureValidation, - TokenReplayValidator = SkipValidationDelegates.SkipTokenReplayValidation, - TokenTypeValidator = tokenTypeValidator - }; - - ExtraStackFrames = extraStackFrames; - } - - public JsonWebToken JsonWebToken { get; } - - public JsonWebTokenHandler JsonWebTokenHandler { get; } = new JsonWebTokenHandler(); - - public bool IsValid { get; set; } - - internal ValidatedTokenType ValidatedTokenType { get; set; } - - internal TokenTypeValidationError? TokenTypeValidationError { get; set; } - - internal int ExtraStackFrames { get; } + return ExtensibilityTesting.GenerateTokenTypeExtensibilityTestCases( + tokenHandlerType, + extraStackFrames, + "JsonWebTokenHandler.ValidateToken.Internal.cs"); } } } diff --git a/test/Microsoft.IdentityModel.TestUtils/TokenValidationExtensibility/Tests/AlgorithmExtensibilityTestCases.cs b/test/Microsoft.IdentityModel.TestUtils/TokenValidationExtensibility/Tests/AlgorithmExtensibilityTestCases.cs new file mode 100644 index 0000000000..d28fefce62 --- /dev/null +++ b/test/Microsoft.IdentityModel.TestUtils/TokenValidationExtensibility/Tests/AlgorithmExtensibilityTestCases.cs @@ -0,0 +1,228 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Diagnostics; +using Xunit; +using Microsoft.IdentityModel.Tokens; +using Microsoft.IdentityModel.Logging; + +#nullable enable +namespace Microsoft.IdentityModel.TestUtils.TokenValidationExtensibility.Tests +{ + public partial class ExtensibilityTesting + { + public static TheoryData GenerateAlgorithmExtensibilityTestCases( + string tokenHandlerType, + int extraStackFrames, + string stackFrameFileName) + { + TheoryData theoryData = new(); + CallContext callContext = new CallContext(); + + #region return CustomAlgorithmValidationError + // Test cases where delegate is overridden and return a CustomAlgorithmValidationError + // CustomAlgorithmValidationError : AlgorithmValidationError, ExceptionType: SecurityTokenInvalidAlgorithmException + theoryData.Add(new AlgorithmExtensibilityTheoryData( + "CustomAlgorithmValidatorDelegate", + tokenHandlerType, + CustomAlgorithmValidationDelegates.CustomAlgorithmValidatorDelegate, + extraStackFrames: extraStackFrames) + { + ExpectedException = new ExpectedException( + typeof(SecurityTokenInvalidSignatureException), + "IDX10518:", + typeof(SecurityTokenInvalidAlgorithmException)), + ExpectedInnerException = new ExpectedException( + typeof(SecurityTokenInvalidAlgorithmException), + nameof(CustomAlgorithmValidationDelegates.CustomAlgorithmValidatorDelegate)), + ValidationError = new CustomAlgorithmValidationError( + new MessageDetail( + nameof(CustomAlgorithmValidationDelegates.CustomAlgorithmValidatorDelegate), null), + ValidationFailureType.AlgorithmValidationFailed, + typeof(SecurityTokenInvalidAlgorithmException), + new StackFrame("CustomAlgorithmValidationDelegates.cs", 0), + "algorithm") + }); + + // CustomAlgorithmValidationError : AlgorithmValidationError, ExceptionType: CustomSecurityTokenInvalidAlgorithmException : SecurityTokenInvalidAlgorithmException + theoryData.Add(new AlgorithmExtensibilityTheoryData( + "CustomAlgorithmValidatorCustomExceptionDelegate", + tokenHandlerType, + CustomAlgorithmValidationDelegates.CustomAlgorithmValidatorCustomExceptionDelegate, + extraStackFrames: extraStackFrames) + { + ExpectedException = new ExpectedException( + typeof(SecurityTokenInvalidSignatureException), + "IDX10518:", + typeof(CustomSecurityTokenInvalidAlgorithmException)), + ExpectedInnerException = new ExpectedException( + typeof(CustomSecurityTokenInvalidAlgorithmException), + nameof(CustomAlgorithmValidationDelegates.CustomAlgorithmValidatorCustomExceptionDelegate)), + ValidationError = new CustomAlgorithmValidationError( + new MessageDetail( + nameof(CustomAlgorithmValidationDelegates.CustomAlgorithmValidatorCustomExceptionDelegate), null), + ValidationFailureType.AlgorithmValidationFailed, + typeof(CustomSecurityTokenInvalidAlgorithmException), + new StackFrame("CustomAlgorithmValidationDelegates.cs", 0), + "algorithm"), + }); + + // CustomAlgorithmValidationError : AlgorithmValidationError, ExceptionType: NotSupportedException : SystemException + theoryData.Add(new AlgorithmExtensibilityTheoryData( + "CustomAlgorithmValidatorUnknownExceptionDelegate", + tokenHandlerType, + CustomAlgorithmValidationDelegates.CustomAlgorithmValidatorUnknownExceptionDelegate, + extraStackFrames: extraStackFrames) + { + // CustomAlgorithmValidationError does not handle the exception type 'NotSupportedException' + ExpectedException = new ExpectedException( + typeof(SecurityTokenInvalidSignatureException), + "IDX10518:", + typeof(SecurityTokenException)), + ExpectedInnerException = ExpectedException.SecurityTokenException( + LogHelper.FormatInvariant( + Tokens.LogMessages.IDX10002, // "IDX10002: Unknown exception type returned. Type: '{0}'. Message: '{1}'."; + typeof(NotSupportedException), + nameof(CustomAlgorithmValidationDelegates.CustomAlgorithmValidatorUnknownExceptionDelegate))), + ValidationError = new CustomAlgorithmValidationError( + new MessageDetail( + nameof(CustomAlgorithmValidationDelegates.CustomAlgorithmValidatorUnknownExceptionDelegate), null), + ValidationFailureType.AlgorithmValidationFailed, + typeof(NotSupportedException), + new StackFrame("CustomAlgorithmValidationDelegates.cs", 0), + "algorithm"), + }); + + // CustomAlgorithmValidationError : AlgorithmValidationError, ExceptionType: NotSupportedException : SystemException, ValidationFailureType: CustomAudienceValidationFailureType + theoryData.Add(new AlgorithmExtensibilityTheoryData( + "CustomAlgorithmValidatorCustomExceptionCustomFailureTypeDelegate", + tokenHandlerType, + CustomAlgorithmValidationDelegates.CustomAlgorithmValidatorCustomExceptionCustomFailureTypeDelegate, + extraStackFrames: extraStackFrames) + { + ExpectedException = new ExpectedException( + typeof(SecurityTokenInvalidSignatureException), + "IDX10518:", + typeof(CustomSecurityTokenInvalidAlgorithmException)), + ExpectedInnerException = new ExpectedException( + typeof(CustomSecurityTokenInvalidAlgorithmException), + nameof(CustomAlgorithmValidationDelegates.CustomAlgorithmValidatorCustomExceptionCustomFailureTypeDelegate)), + ValidationError = new CustomAlgorithmValidationError( + new MessageDetail( + nameof(CustomAlgorithmValidationDelegates.CustomAlgorithmValidatorCustomExceptionCustomFailureTypeDelegate), null), + CustomAlgorithmValidationError.CustomAlgorithmValidationFailureType, + typeof(CustomSecurityTokenInvalidAlgorithmException), + new StackFrame("CustomAlgorithmValidationDelegates.cs", 0), + "algorithm"), + }); + #endregion + + #region return AlgorithmValidationError + // Test cases where delegate is overridden and return an AlgorithmValidationError + // AlgorithmValidationError : ValidationError, ExceptionType: SecurityTokenInvalidAlgorithmException + theoryData.Add(new AlgorithmExtensibilityTheoryData( + "AlgorithmValidatorDelegate", + tokenHandlerType, + CustomAlgorithmValidationDelegates.AlgorithmValidatorDelegate, + extraStackFrames: extraStackFrames) + { + ExpectedException = new ExpectedException( + typeof(SecurityTokenInvalidSignatureException), + "IDX10518:", + typeof(SecurityTokenInvalidAlgorithmException)), + ExpectedInnerException = new ExpectedException( + typeof(SecurityTokenInvalidAlgorithmException), + nameof(CustomAlgorithmValidationDelegates.AlgorithmValidatorDelegate)), + ValidationError = new AlgorithmValidationError( + new MessageDetail( + nameof(CustomAlgorithmValidationDelegates.AlgorithmValidatorDelegate), null), + ValidationFailureType.AlgorithmValidationFailed, + typeof(SecurityTokenInvalidAlgorithmException), + new StackFrame("CustomAlgorithmValidationDelegates.cs", 0), + "algorithm") + }); + + // AlgorithmValidationError : ValidationError, ExceptionType: CustomSecurityTokenInvalidAlgorithmException : SecurityTokenInvalidAlgorithmException + theoryData.Add(new AlgorithmExtensibilityTheoryData( + "AlgorithmValidatorCustomAlgorithmExceptionTypeDelegate", + tokenHandlerType, + CustomAlgorithmValidationDelegates.AlgorithmValidatorCustomAlgorithmExceptionTypeDelegate, + extraStackFrames: extraStackFrames) + { + // AlgorithmValidationError does not handle the exception type 'CustomSecurityTokenInvalidAlgorithmException' + ExpectedException = new ExpectedException( + typeof(SecurityTokenInvalidSignatureException), + "IDX10518:", + typeof(SecurityTokenException)), + ExpectedInnerException = ExpectedException.SecurityTokenException( + LogHelper.FormatInvariant( + Tokens.LogMessages.IDX10002, // "IDX10002: Unknown exception type returned. Type: '{0}'. Message: '{1}'."; + typeof(CustomSecurityTokenInvalidAlgorithmException), + nameof(CustomAlgorithmValidationDelegates.AlgorithmValidatorCustomAlgorithmExceptionTypeDelegate))), + ValidationError = new AlgorithmValidationError( + new MessageDetail( + nameof(CustomAlgorithmValidationDelegates.AlgorithmValidatorCustomAlgorithmExceptionTypeDelegate), null), + ValidationFailureType.AlgorithmValidationFailed, + typeof(CustomSecurityTokenInvalidAlgorithmException), + new StackFrame("CustomAlgorithmValidationDelegates.cs", 0), + "algorithm") + }); + + // AlgorithmValidationError : ValidationError, ExceptionType: CustomSecurityTokenException : SystemException + theoryData.Add(new AlgorithmExtensibilityTheoryData( + "AlgorithmValidatorCustomExceptionTypeDelegate", + tokenHandlerType, + CustomAlgorithmValidationDelegates.AlgorithmValidatorCustomExceptionTypeDelegate, + extraStackFrames: extraStackFrames) + { + // AlgorithmValidationError does not handle the exception type 'CustomSecurityTokenException' + ExpectedException = new ExpectedException( + typeof(SecurityTokenInvalidSignatureException), + "IDX10518:", + typeof(SecurityTokenException)), + ExpectedInnerException = ExpectedException.SecurityTokenException( + LogHelper.FormatInvariant( + Tokens.LogMessages.IDX10002, // "IDX10002: Unknown exception type returned. Type: '{0}'. Message: '{1}'."; + typeof(CustomSecurityTokenException), + nameof(CustomAlgorithmValidationDelegates.AlgorithmValidatorCustomExceptionTypeDelegate))), + ValidationError = new AlgorithmValidationError( + new MessageDetail( + nameof(CustomAlgorithmValidationDelegates.AlgorithmValidatorCustomExceptionTypeDelegate), null), + ValidationFailureType.AlgorithmValidationFailed, + typeof(CustomSecurityTokenException), + new StackFrame("CustomAlgorithmValidationDelegates.cs", 0), + "algorithm") + }); + + // SignatureValidationError : ValidationError, ExceptionType: SecurityTokenInvalidSignatureException, inner: CustomSecurityTokenInvalidAlgorithmException + theoryData.Add(new AlgorithmExtensibilityTheoryData( + "AlgorithmValidatorThrows", + tokenHandlerType, + CustomAlgorithmValidationDelegates.AlgorithmValidatorThrows, + extraStackFrames: extraStackFrames + 1) + { + ExpectedException = new ExpectedException( + typeof(SecurityTokenInvalidSignatureException), + "IDX10273:", + typeof(CustomSecurityTokenInvalidAlgorithmException)), + ExpectedInnerException = new ExpectedException( + typeof(CustomSecurityTokenInvalidAlgorithmException), + nameof(CustomAlgorithmValidationDelegates.AlgorithmValidatorThrows)), + ValidationError = new SignatureValidationError( + new MessageDetail( + string.Format(Tokens.LogMessages.IDX10273), null), + ValidationFailureType.AlgorithmValidatorThrew, + typeof(SecurityTokenInvalidSignatureException), + new StackFrame(stackFrameFileName, 0), + null, // no inner validation error + new CustomSecurityTokenInvalidAlgorithmException(nameof(CustomAlgorithmValidationDelegates.AlgorithmValidatorThrows), null) + ) + }); + #endregion + + return theoryData; + } + } +} +#nullable restore diff --git a/test/Microsoft.IdentityModel.TestUtils/TokenValidationExtensibility/Tests/AlgorithmExtensibilityTheoryData.cs b/test/Microsoft.IdentityModel.TestUtils/TokenValidationExtensibility/Tests/AlgorithmExtensibilityTheoryData.cs new file mode 100644 index 0000000000..90a6888d32 --- /dev/null +++ b/test/Microsoft.IdentityModel.TestUtils/TokenValidationExtensibility/Tests/AlgorithmExtensibilityTheoryData.cs @@ -0,0 +1,29 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using Microsoft.IdentityModel.Tokens; + +#nullable enable +namespace Microsoft.IdentityModel.TestUtils.TokenValidationExtensibility.Tests +{ + public class AlgorithmExtensibilityTheoryData : ExtensibilityTheoryData + { + internal AlgorithmExtensibilityTheoryData( + string testId, + string tokenHandlerType, + AlgorithmValidationDelegate algorithmValidationDelegate, + int extraStackFrames) : base(testId, tokenHandlerType, extraStackFrames) + { + SecurityTokenDescriptor = new() + { + Issuer = Default.Issuer, + SigningCredentials = KeyingMaterial.DefaultX509SigningCreds_2048_RsaSha2_Sha2, + }; + + ValidationParameters.AlgorithmValidator = algorithmValidationDelegate; + ValidationParameters.SignatureValidator = null; + ValidationParameters.IssuerSigningKeys.Add(KeyingMaterial.DefaultX509SigningCreds_2048_RsaSha2_Sha2.Key); + } + } +} +#nullable restore diff --git a/test/Microsoft.IdentityModel.TestUtils/TokenValidationExtensibility/Tests/ExtensibilityTheoryData.cs b/test/Microsoft.IdentityModel.TestUtils/TokenValidationExtensibility/Tests/ExtensibilityTheoryData.cs index c358e7ad45..6a2763c5c3 100644 --- a/test/Microsoft.IdentityModel.TestUtils/TokenValidationExtensibility/Tests/ExtensibilityTheoryData.cs +++ b/test/Microsoft.IdentityModel.TestUtils/TokenValidationExtensibility/Tests/ExtensibilityTheoryData.cs @@ -83,6 +83,8 @@ public SecurityTokenDescriptor SecurityTokenDescriptor internal ValidationError? ValidationError { get; set; } internal int ExtraStackFrames { get; } + + internal ExpectedException? ExpectedInnerException { get; set; } } } #nullable restore diff --git a/test/Microsoft.IdentityModel.TestUtils/TokenValidationExtensibility/Tests/IExtensibilityTestingTokenHandler.cs b/test/Microsoft.IdentityModel.TestUtils/TokenValidationExtensibility/Tests/IExtensibilityTestingTokenHandler.cs index 62902868cd..8d2bfd5a03 100644 --- a/test/Microsoft.IdentityModel.TestUtils/TokenValidationExtensibility/Tests/IExtensibilityTestingTokenHandler.cs +++ b/test/Microsoft.IdentityModel.TestUtils/TokenValidationExtensibility/Tests/IExtensibilityTestingTokenHandler.cs @@ -8,6 +8,7 @@ using Microsoft.IdentityModel.Tokens.Saml; using Microsoft.IdentityModel.Tokens.Saml2; +#nullable enable namespace Microsoft.IdentityModel.TestUtils.TokenValidationExtensibility.Tests { // This interface is used to test the extensibility of the ValidateTokenAsync method @@ -93,3 +94,4 @@ public SecurityToken CreateToken(SecurityTokenDescriptor tokenDescriptor) } } } +#nullable restore diff --git a/test/Microsoft.IdentityModel.TestUtils/TokenValidationExtensibility/Tests/IssuerExtensibilityTestCases.cs b/test/Microsoft.IdentityModel.TestUtils/TokenValidationExtensibility/Tests/IssuerExtensibilityTestCases.cs index 9a6a669aa9..296708b70a 100644 --- a/test/Microsoft.IdentityModel.TestUtils/TokenValidationExtensibility/Tests/IssuerExtensibilityTestCases.cs +++ b/test/Microsoft.IdentityModel.TestUtils/TokenValidationExtensibility/Tests/IssuerExtensibilityTestCases.cs @@ -7,6 +7,7 @@ using Microsoft.IdentityModel.Tokens; using Microsoft.IdentityModel.Logging; +#nullable enable namespace Microsoft.IdentityModel.TestUtils.TokenValidationExtensibility.Tests { public partial class ExtensibilityTesting @@ -203,3 +204,4 @@ public static TheoryData GenerateIssuerExtensibil } } } +#nullable restore diff --git a/test/Microsoft.IdentityModel.TestUtils/TokenValidationExtensibility/Tests/IssuerExtensibilityTheoryData.cs b/test/Microsoft.IdentityModel.TestUtils/TokenValidationExtensibility/Tests/IssuerExtensibilityTheoryData.cs index 12b4c53c28..329658ddde 100644 --- a/test/Microsoft.IdentityModel.TestUtils/TokenValidationExtensibility/Tests/IssuerExtensibilityTheoryData.cs +++ b/test/Microsoft.IdentityModel.TestUtils/TokenValidationExtensibility/Tests/IssuerExtensibilityTheoryData.cs @@ -3,6 +3,7 @@ using Microsoft.IdentityModel.Tokens; +#nullable enable namespace Microsoft.IdentityModel.TestUtils.TokenValidationExtensibility.Tests { public class IssuerExtensibilityTheoryData : ExtensibilityTheoryData @@ -23,3 +24,4 @@ internal IssuerExtensibilityTheoryData( } } } +#nullable restore diff --git a/test/Microsoft.IdentityModel.TestUtils/TokenValidationExtensibility/Tests/IssuerSigningKeyExtensibilityTestCases.cs b/test/Microsoft.IdentityModel.TestUtils/TokenValidationExtensibility/Tests/IssuerSigningKeyExtensibilityTestCases.cs new file mode 100644 index 0000000000..e504f3c82a --- /dev/null +++ b/test/Microsoft.IdentityModel.TestUtils/TokenValidationExtensibility/Tests/IssuerSigningKeyExtensibilityTestCases.cs @@ -0,0 +1,198 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Diagnostics; +using Xunit; +using Microsoft.IdentityModel.Tokens; +using Microsoft.IdentityModel.Logging; + +#nullable enable +namespace Microsoft.IdentityModel.TestUtils.TokenValidationExtensibility.Tests +{ + public partial class ExtensibilityTesting + { + public static TheoryData GenerateIssuerSigningKeyExtensibilityTestCases( + string tokenHandlerType, + int extraStackFrames, + string stackFrameFileName) + { + var theoryData = new TheoryData(); + CallContext callContext = new CallContext(); + string issuerGuid = Guid.NewGuid().ToString(); + + #region return CustomIssuerSigningKeyValidationError + // Test cases where delegate is overridden and return a CustomIssuerSigningKeyValidationError + // CustomIssuerSigningKeyValidationError : IssuerSigningKeyValidationError, ExceptionType: SecurityTokenInvalidIssuerSigningKeyException + theoryData.Add(new IssuerSigningKeyExtensibilityTheoryData( + "CustomIssuerSigningKeyValidatorDelegate", + tokenHandlerType, + CustomIssuerSigningKeyValidationDelegates.CustomIssuerSigningKeyValidatorDelegate, + extraStackFrames: extraStackFrames) + { + ExpectedException = new ExpectedException( + typeof(SecurityTokenInvalidSigningKeyException), + nameof(CustomIssuerSigningKeyValidationDelegates.CustomIssuerSigningKeyValidatorDelegate)), + ValidationError = new CustomIssuerSigningKeyValidationError( + new MessageDetail( + nameof(CustomIssuerSigningKeyValidationDelegates.CustomIssuerSigningKeyValidatorDelegate), null), + ValidationFailureType.SigningKeyValidationFailed, + typeof(SecurityTokenInvalidSigningKeyException), + new StackFrame("CustomIssuerSigningKeyValidationDelegates.cs", 0), + null) + }); + + // CustomIssuerSigningKeyValidationError : IssuerSigningKeyValidationError, ExceptionType: CustomSecurityTokenInvalidIssuerSigningKeyException : SecurityTokenInvalidIssuerSigningKeyException + theoryData.Add(new IssuerSigningKeyExtensibilityTheoryData( + "CustomIssuerSigningKeyValidatorCustomExceptionDelegate", + tokenHandlerType, + CustomIssuerSigningKeyValidationDelegates.CustomIssuerSigningKeyValidatorCustomExceptionDelegate, + extraStackFrames: extraStackFrames) + { + ExpectedException = new ExpectedException( + typeof(CustomSecurityTokenInvalidSigningKeyException), + nameof(CustomIssuerSigningKeyValidationDelegates.CustomIssuerSigningKeyValidatorCustomExceptionDelegate)), + ValidationError = new CustomIssuerSigningKeyValidationError( + new MessageDetail( + nameof(CustomIssuerSigningKeyValidationDelegates.CustomIssuerSigningKeyValidatorCustomExceptionDelegate), null), + ValidationFailureType.SigningKeyValidationFailed, + typeof(CustomSecurityTokenInvalidSigningKeyException), + new StackFrame("CustomIssuerSigningKeyValidationDelegates.cs", 0), + null) + }); + + // CustomIssuerSigningKeyValidationError : IssuerSigningKeyValidationError, ExceptionType: NotSupportedException : SystemException + theoryData.Add(new IssuerSigningKeyExtensibilityTheoryData( + "CustomIssuerSigningKeyValidatorUnknownExceptionDelegate", + tokenHandlerType, + CustomIssuerSigningKeyValidationDelegates.CustomIssuerSigningKeyValidatorUnknownExceptionDelegate, + extraStackFrames: extraStackFrames) + { + // CustomIssuerSigningKeyValidationError does not handle the exception type 'NotSupportedException' + ExpectedException = ExpectedException.SecurityTokenException( + LogHelper.FormatInvariant( + Tokens.LogMessages.IDX10002, // "IDX10002: Unknown exception type returned. Type: '{0}'. Message: '{1}'."; + typeof(NotSupportedException), + nameof(CustomIssuerSigningKeyValidationDelegates.CustomIssuerSigningKeyValidatorUnknownExceptionDelegate))), + ValidationError = new CustomIssuerSigningKeyValidationError( + new MessageDetail( + nameof(CustomIssuerSigningKeyValidationDelegates.CustomIssuerSigningKeyValidatorUnknownExceptionDelegate), null), + ValidationFailureType.SigningKeyValidationFailed, + typeof(NotSupportedException), + new StackFrame("CustomIssuerSigningKeyValidationDelegates.cs", 0), + null) + }); + + // CustomIssuerSigningKeyValidationError : IssuerSigningKeyValidationError, ExceptionType: NotSupportedException : SystemException, ValidationFailureType: CustomAudienceValidationFailureType + theoryData.Add(new IssuerSigningKeyExtensibilityTheoryData( + "CustomIssuerSigningKeyValidatorCustomExceptionCustomFailureTypeDelegate", + tokenHandlerType, + CustomIssuerSigningKeyValidationDelegates.CustomIssuerSigningKeyValidatorCustomExceptionCustomFailureTypeDelegate, + extraStackFrames: extraStackFrames) + { + ExpectedException = new ExpectedException( + typeof(CustomSecurityTokenInvalidSigningKeyException), + nameof(CustomIssuerSigningKeyValidationDelegates.CustomIssuerSigningKeyValidatorCustomExceptionCustomFailureTypeDelegate)), + ValidationError = new CustomIssuerSigningKeyValidationError( + new MessageDetail( + nameof(CustomIssuerSigningKeyValidationDelegates.CustomIssuerSigningKeyValidatorCustomExceptionCustomFailureTypeDelegate), null), + CustomIssuerSigningKeyValidationError.CustomIssuerSigningKeyValidationFailureType, + typeof(CustomSecurityTokenInvalidSigningKeyException), + new StackFrame("CustomIssuerSigningKeyValidationDelegates.cs", 0), + null), + }); + #endregion + + #region return IssuerSigningKeyValidationError + // Test cases where delegate is overridden and return an IssuerSigningKeyValidationError + // IssuerSigningKeyValidationError : ValidationError, ExceptionType: SecurityTokenInvalidIssuerSigningKeyException + theoryData.Add(new IssuerSigningKeyExtensibilityTheoryData( + "IssuerSigningKeyValidatorDelegate", + tokenHandlerType, + CustomIssuerSigningKeyValidationDelegates.IssuerSigningKeyValidatorDelegate, + extraStackFrames: extraStackFrames) + { + ExpectedException = new ExpectedException( + typeof(SecurityTokenInvalidSigningKeyException), + nameof(CustomIssuerSigningKeyValidationDelegates.IssuerSigningKeyValidatorDelegate)), + ValidationError = new IssuerSigningKeyValidationError( + new MessageDetail( + nameof(CustomIssuerSigningKeyValidationDelegates.IssuerSigningKeyValidatorDelegate), null), + ValidationFailureType.SigningKeyValidationFailed, + typeof(SecurityTokenInvalidSigningKeyException), + new StackFrame("CustomIssuerSigningKeyValidationDelegates.cs", 0), + null) + }); + + // IssuerSigningKeyValidationError : ValidationError, ExceptionType: CustomSecurityTokenInvalidIssuerSigningKeyException : SecurityTokenInvalidIssuerSigningKeyException + theoryData.Add(new IssuerSigningKeyExtensibilityTheoryData( + "IssuerSigningKeyValidatorCustomIssuerSigningKeyExceptionTypeDelegate", + tokenHandlerType, + CustomIssuerSigningKeyValidationDelegates.IssuerSigningKeyValidatorCustomIssuerSigningKeyExceptionTypeDelegate, + extraStackFrames: extraStackFrames) + { + // IssuerSigningKeyValidationError does not handle the exception type 'CustomSecurityTokenInvalidIssuerSigningKeyException' + ExpectedException = ExpectedException.SecurityTokenException( + LogHelper.FormatInvariant( + Tokens.LogMessages.IDX10002, // "IDX10002: Unknown exception type returned. Type: '{0}'. Message: '{1}'."; + typeof(CustomSecurityTokenInvalidSigningKeyException), + nameof(CustomIssuerSigningKeyValidationDelegates.IssuerSigningKeyValidatorCustomIssuerSigningKeyExceptionTypeDelegate))), + ValidationError = new IssuerSigningKeyValidationError( + new MessageDetail( + nameof(CustomIssuerSigningKeyValidationDelegates.IssuerSigningKeyValidatorCustomIssuerSigningKeyExceptionTypeDelegate), null), + ValidationFailureType.SigningKeyValidationFailed, + typeof(CustomSecurityTokenInvalidSigningKeyException), + new StackFrame("CustomIssuerSigningKeyValidationDelegates.cs", 0), + null) + }); + + // IssuerSigningKeyValidationError : ValidationError, ExceptionType: CustomSecurityTokenException : SystemException + theoryData.Add(new IssuerSigningKeyExtensibilityTheoryData( + "IssuerSigningKeyValidatorCustomExceptionTypeDelegate", + tokenHandlerType, + CustomIssuerSigningKeyValidationDelegates.IssuerSigningKeyValidatorCustomExceptionTypeDelegate, + extraStackFrames: extraStackFrames) + { + // IssuerSigningKeyValidationError does not handle the exception type 'CustomSecurityTokenException' + ExpectedException = ExpectedException.SecurityTokenException( + LogHelper.FormatInvariant( + Tokens.LogMessages.IDX10002, // "IDX10002: Unknown exception type returned. Type: '{0}'. Message: '{1}'."; + typeof(CustomSecurityTokenException), + nameof(CustomIssuerSigningKeyValidationDelegates.IssuerSigningKeyValidatorCustomExceptionTypeDelegate))), + ValidationError = new IssuerSigningKeyValidationError( + new MessageDetail( + nameof(CustomIssuerSigningKeyValidationDelegates.IssuerSigningKeyValidatorCustomExceptionTypeDelegate), null), + ValidationFailureType.SigningKeyValidationFailed, + typeof(CustomSecurityTokenException), + new StackFrame("CustomIssuerSigningKeyValidationDelegates.cs", 0), + null) + }); + + // IssuerSigningKeyValidationError : ValidationError, ExceptionType: SecurityTokenInvalidIssuerSigningKeyException, inner: CustomSecurityTokenInvalidIssuerSigningKeyException + theoryData.Add(new IssuerSigningKeyExtensibilityTheoryData( + "IssuerSigningKeyValidatorThrows", + tokenHandlerType, + CustomIssuerSigningKeyValidationDelegates.IssuerSigningKeyValidatorThrows, + extraStackFrames: extraStackFrames - 1) + { + ExpectedException = new ExpectedException( + typeof(SecurityTokenInvalidSigningKeyException), + string.Format(Tokens.LogMessages.IDX10274), + typeof(CustomSecurityTokenInvalidSigningKeyException)), + ValidationError = new IssuerSigningKeyValidationError( + new MessageDetail( + string.Format(Tokens.LogMessages.IDX10274), null), + ValidationFailureType.IssuerSigningKeyValidatorThrew, + typeof(SecurityTokenInvalidSigningKeyException), + new StackFrame(stackFrameFileName, 0), + null, + new SecurityTokenInvalidSigningKeyException(nameof(CustomIssuerSigningKeyValidationDelegates.IssuerSigningKeyValidatorThrows)) + ) + }); + #endregion + + return theoryData; + } + } +} +#nullable restore diff --git a/test/Microsoft.IdentityModel.TestUtils/TokenValidationExtensibility/Tests/IssuerSigningKeyExtensibilityTheoryData.cs b/test/Microsoft.IdentityModel.TestUtils/TokenValidationExtensibility/Tests/IssuerSigningKeyExtensibilityTheoryData.cs new file mode 100644 index 0000000000..990ed5152a --- /dev/null +++ b/test/Microsoft.IdentityModel.TestUtils/TokenValidationExtensibility/Tests/IssuerSigningKeyExtensibilityTheoryData.cs @@ -0,0 +1,35 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using Microsoft.IdentityModel.Tokens; + +#nullable enable +namespace Microsoft.IdentityModel.TestUtils.TokenValidationExtensibility.Tests +{ + public class IssuerSigningKeyExtensibilityTheoryData : ExtensibilityTheoryData + { + internal IssuerSigningKeyExtensibilityTheoryData( + string testId, + string tokenHandlerType, + IssuerSigningKeyValidationDelegate issuerSigningKeyValidationDelegate, + int extraStackFrames) : base(testId, tokenHandlerType, extraStackFrames) + { + var signingCredentials = KeyingMaterial.DefaultX509SigningCreds_2048_RsaSha2_Sha2; + + SecurityTokenDescriptor = new() + { + Issuer = Default.Issuer, + SigningCredentials = signingCredentials, + }; + + ValidationParameters.IssuerSigningKeyValidator = issuerSigningKeyValidationDelegate; + ValidationParameters.SignatureValidator = (SecurityToken token, ValidationParameters validationParameters, BaseConfiguration? configuration, CallContext callContext) => + { + token.SigningKey = signingCredentials.Key; + + return signingCredentials.Key; + }; + } + } +} +#nullable restore diff --git a/test/Microsoft.IdentityModel.TestUtils/TokenValidationExtensibility/Tests/SignatureExtensibilityTestCases.cs b/test/Microsoft.IdentityModel.TestUtils/TokenValidationExtensibility/Tests/SignatureExtensibilityTestCases.cs new file mode 100644 index 0000000000..d943f6041d --- /dev/null +++ b/test/Microsoft.IdentityModel.TestUtils/TokenValidationExtensibility/Tests/SignatureExtensibilityTestCases.cs @@ -0,0 +1,191 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Diagnostics; +using Xunit; +using Microsoft.IdentityModel.Tokens; +using Microsoft.IdentityModel.Logging; + +#nullable enable +namespace Microsoft.IdentityModel.TestUtils.TokenValidationExtensibility.Tests +{ + public partial class ExtensibilityTesting + { + public static TheoryData GenerateSignatureExtensibilityTestCases( + string tokenHandlerType, + int extraStackFrames, + string stackFrameFileName) + { + var theoryData = new TheoryData(); + CallContext callContext = new CallContext(); + string issuerGuid = Guid.NewGuid().ToString(); + + #region return CustomSignatureValidationError + // Test cases where delegate is overridden and return a CustomSignatureValidationError + // CustomSignatureValidationError : SignatureValidationError, ExceptionType: SecurityTokenInvalidSignatureException + theoryData.Add(new SignatureExtensibilityTheoryData( + "CustomSignatureValidatorDelegate", + tokenHandlerType, + CustomSignatureValidationDelegates.CustomSignatureValidatorDelegate, + extraStackFrames: extraStackFrames) + { + ExpectedException = new ExpectedException( + typeof(SecurityTokenInvalidSignatureException), + nameof(CustomSignatureValidationDelegates.CustomSignatureValidatorDelegate)), + ValidationError = new CustomSignatureValidationError( + new MessageDetail( + nameof(CustomSignatureValidationDelegates.CustomSignatureValidatorDelegate), null), + ValidationFailureType.SignatureValidationFailed, + typeof(SecurityTokenInvalidSignatureException), + new StackFrame("CustomSignatureValidationDelegates.cs", 0)) + }); + + // CustomSignatureValidationError : SignatureValidationError, ExceptionType: CustomSecurityTokenInvalidSignatureException : SecurityTokenInvalidSignatureException + theoryData.Add(new SignatureExtensibilityTheoryData( + "CustomSignatureValidatorCustomExceptionDelegate", + tokenHandlerType, + CustomSignatureValidationDelegates.CustomSignatureValidatorCustomExceptionDelegate, + extraStackFrames: extraStackFrames) + { + ExpectedException = new ExpectedException( + typeof(CustomSecurityTokenInvalidSignatureException), + nameof(CustomSignatureValidationDelegates.CustomSignatureValidatorCustomExceptionDelegate)), + ValidationError = new CustomSignatureValidationError( + new MessageDetail( + nameof(CustomSignatureValidationDelegates.CustomSignatureValidatorCustomExceptionDelegate), null), + ValidationFailureType.SignatureValidationFailed, + typeof(CustomSecurityTokenInvalidSignatureException), + new StackFrame("CustomSignatureValidationDelegates.cs", 0)), + }); + + // CustomSignatureValidationError : SignatureValidationError, ExceptionType: NotSupportedException : SystemException + theoryData.Add(new SignatureExtensibilityTheoryData( + "CustomSignatureValidatorUnknownExceptionDelegate", + tokenHandlerType, + CustomSignatureValidationDelegates.CustomSignatureValidatorUnknownExceptionDelegate, + extraStackFrames: extraStackFrames) + { + // CustomSignatureValidationError does not handle the exception type 'NotSupportedException' + ExpectedException = ExpectedException.SecurityTokenException( + LogHelper.FormatInvariant( + Tokens.LogMessages.IDX10002, // "IDX10002: Unknown exception type returned. Type: '{0}'. Message: '{1}'."; + typeof(NotSupportedException), + nameof(CustomSignatureValidationDelegates.CustomSignatureValidatorUnknownExceptionDelegate))), + ValidationError = new CustomSignatureValidationError( + new MessageDetail( + nameof(CustomSignatureValidationDelegates.CustomSignatureValidatorUnknownExceptionDelegate), null), + ValidationFailureType.SignatureValidationFailed, + typeof(NotSupportedException), + new StackFrame("CustomSignatureValidationDelegates.cs", 0)), + }); + + // CustomSignatureValidationError : SignatureValidationError, ExceptionType: NotSupportedException : SystemException, ValidationFailureType: CustomAudienceValidationFailureType + theoryData.Add(new SignatureExtensibilityTheoryData( + "CustomSignatureValidatorCustomExceptionCustomFailureTypeDelegate", + tokenHandlerType, + CustomSignatureValidationDelegates.CustomSignatureValidatorCustomExceptionCustomFailureTypeDelegate, + extraStackFrames: extraStackFrames) + { + ExpectedException = new ExpectedException( + typeof(CustomSecurityTokenInvalidSignatureException), + nameof(CustomSignatureValidationDelegates.CustomSignatureValidatorCustomExceptionCustomFailureTypeDelegate)), + ValidationError = new CustomSignatureValidationError( + new MessageDetail( + nameof(CustomSignatureValidationDelegates.CustomSignatureValidatorCustomExceptionCustomFailureTypeDelegate), null), + CustomSignatureValidationError.CustomSignatureValidationFailureType, + typeof(CustomSecurityTokenInvalidSignatureException), + new StackFrame("CustomSignatureValidationDelegates.cs", 0)), + }); + #endregion + + #region return SignatureValidationError + // Test cases where delegate is overridden and return an SignatureValidationError + // SignatureValidationError : ValidationError, ExceptionType: SecurityTokenInvalidSignatureException + theoryData.Add(new SignatureExtensibilityTheoryData( + "SignatureValidatorDelegate", + tokenHandlerType, + CustomSignatureValidationDelegates.SignatureValidatorDelegate, + extraStackFrames: extraStackFrames) + { + ExpectedException = new ExpectedException( + typeof(SecurityTokenInvalidSignatureException), + nameof(CustomSignatureValidationDelegates.SignatureValidatorDelegate)), + ValidationError = new SignatureValidationError( + new MessageDetail( + nameof(CustomSignatureValidationDelegates.SignatureValidatorDelegate), null), + ValidationFailureType.SignatureValidationFailed, + typeof(SecurityTokenInvalidSignatureException), + new StackFrame("CustomSignatureValidationDelegates.cs", 0)) + }); + + // SignatureValidationError : ValidationError, ExceptionType: CustomSecurityTokenInvalidSignatureException : SecurityTokenInvalidSignatureException + theoryData.Add(new SignatureExtensibilityTheoryData( + "SignatureValidatorCustomSignatureExceptionTypeDelegate", + tokenHandlerType, + CustomSignatureValidationDelegates.SignatureValidatorCustomSignatureExceptionTypeDelegate, + extraStackFrames: extraStackFrames) + { + // SignatureValidationError does not handle the exception type 'CustomSecurityTokenInvalidSignatureException' + ExpectedException = ExpectedException.SecurityTokenException( + LogHelper.FormatInvariant( + Tokens.LogMessages.IDX10002, // "IDX10002: Unknown exception type returned. Type: '{0}'. Message: '{1}'."; + typeof(CustomSecurityTokenInvalidSignatureException), + nameof(CustomSignatureValidationDelegates.SignatureValidatorCustomSignatureExceptionTypeDelegate))), + ValidationError = new SignatureValidationError( + new MessageDetail( + nameof(CustomSignatureValidationDelegates.SignatureValidatorCustomSignatureExceptionTypeDelegate), null), + ValidationFailureType.SignatureValidationFailed, + typeof(CustomSecurityTokenInvalidSignatureException), + new StackFrame("CustomSignatureValidationDelegates.cs", 0)) + }); + + // SignatureValidationError : ValidationError, ExceptionType: CustomSecurityTokenException : SystemException + theoryData.Add(new SignatureExtensibilityTheoryData( + "SignatureValidatorCustomExceptionTypeDelegate", + tokenHandlerType, + CustomSignatureValidationDelegates.SignatureValidatorCustomExceptionTypeDelegate, + extraStackFrames: extraStackFrames) + { + // SignatureValidationError does not handle the exception type 'CustomSecurityTokenException' + ExpectedException = ExpectedException.SecurityTokenException( + LogHelper.FormatInvariant( + Tokens.LogMessages.IDX10002, // "IDX10002: Unknown exception type returned. Type: '{0}'. Message: '{1}'."; + typeof(CustomSecurityTokenException), + nameof(CustomSignatureValidationDelegates.SignatureValidatorCustomExceptionTypeDelegate))), + ValidationError = new SignatureValidationError( + new MessageDetail( + nameof(CustomSignatureValidationDelegates.SignatureValidatorCustomExceptionTypeDelegate), null), + ValidationFailureType.SignatureValidationFailed, + typeof(CustomSecurityTokenException), + new StackFrame("CustomSignatureValidationDelegates.cs", 0)) + }); + + // SignatureValidationError : ValidationError, ExceptionType: SecurityTokenInvalidSignatureException, inner: CustomSecurityTokenInvalidSignatureException + theoryData.Add(new SignatureExtensibilityTheoryData( + "SignatureValidatorThrows", + tokenHandlerType, + CustomSignatureValidationDelegates.SignatureValidatorThrows, + extraStackFrames: extraStackFrames - 1) + { + ExpectedException = new ExpectedException( + typeof(SecurityTokenInvalidSignatureException), + string.Format(Tokens.LogMessages.IDX10272), + typeof(CustomSecurityTokenInvalidSignatureException)), + ValidationError = new SignatureValidationError( + new MessageDetail( + string.Format(Tokens.LogMessages.IDX10272), null), + ValidationFailureType.SignatureValidatorThrew, + typeof(SecurityTokenInvalidSignatureException), + new StackFrame(stackFrameFileName, 0), + null, // no inner validation error + new SecurityTokenInvalidSignatureException(nameof(CustomSignatureValidationDelegates.SignatureValidatorThrows)) + ) + }); + #endregion + + return theoryData; + } + } +} +#nullable restore diff --git a/test/Microsoft.IdentityModel.TestUtils/TokenValidationExtensibility/Tests/SignatureExtensibilityTheoryData.cs b/test/Microsoft.IdentityModel.TestUtils/TokenValidationExtensibility/Tests/SignatureExtensibilityTheoryData.cs new file mode 100644 index 0000000000..f3d222bae8 --- /dev/null +++ b/test/Microsoft.IdentityModel.TestUtils/TokenValidationExtensibility/Tests/SignatureExtensibilityTheoryData.cs @@ -0,0 +1,26 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using Microsoft.IdentityModel.Tokens; + +#nullable enable +namespace Microsoft.IdentityModel.TestUtils.TokenValidationExtensibility.Tests +{ + public class SignatureExtensibilityTheoryData : ExtensibilityTheoryData + { + internal SignatureExtensibilityTheoryData( + string testId, + string tokenHandlerType, + SignatureValidationDelegate signatureValidationDelegate, + int extraStackFrames) : base(testId, tokenHandlerType, extraStackFrames) + { + SecurityTokenDescriptor = new() + { + Issuer = Default.Issuer, + }; + + ValidationParameters.SignatureValidator = signatureValidationDelegate; + } + } +} +#nullable restore diff --git a/test/Microsoft.IdentityModel.TestUtils/TokenValidationExtensibility/Tests/TokenReplayExtensibilityTestCases.cs b/test/Microsoft.IdentityModel.TestUtils/TokenValidationExtensibility/Tests/TokenReplayExtensibilityTestCases.cs new file mode 100644 index 0000000000..2828262df9 --- /dev/null +++ b/test/Microsoft.IdentityModel.TestUtils/TokenValidationExtensibility/Tests/TokenReplayExtensibilityTestCases.cs @@ -0,0 +1,206 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Diagnostics; +using Xunit; +using Microsoft.IdentityModel.Tokens; +using Microsoft.IdentityModel.Logging; + +#nullable enable +namespace Microsoft.IdentityModel.TestUtils.TokenValidationExtensibility.Tests +{ + public partial class ExtensibilityTesting + { + public static TheoryData GenerateTokenReplayExtensibilityTestCases( + string tokenHandlerType, + int extraStackFrames, + string stackFrameFileName) + { + var theoryData = new TheoryData(); + CallContext callContext = new CallContext(); + DateTime expirationTime = DateTime.UtcNow + TimeSpan.FromHours(1); + + #region return CustomTokenReplayValidationError + // Test cases where delegate is overridden and return a CustomTokenReplayValidationError + // CustomTokenReplayValidationError : TokenReplayValidationError, ExceptionType: SecurityTokenReplayDetectedException + theoryData.Add(new TokenReplayExtensibilityTheoryData( + "CustomTokenReplayValidationDelegate", + tokenHandlerType, + expirationTime, + CustomTokenReplayValidationDelegates.CustomTokenReplayValidationDelegate, + extraStackFrames: extraStackFrames) + { + ExpectedException = new ExpectedException( + typeof(SecurityTokenReplayDetectedException), + nameof(CustomTokenReplayValidationDelegates.CustomTokenReplayValidationDelegate)), + ValidationError = new CustomTokenReplayValidationError( + new MessageDetail( + nameof(CustomTokenReplayValidationDelegates.CustomTokenReplayValidationDelegate), null), + ValidationFailureType.TokenReplayValidationFailed, + typeof(SecurityTokenReplayDetectedException), + new StackFrame("CustomTokenReplayValidationDelegates.cs", 0), + expirationTime) + }); + + // CustomTokenReplayValidationError : TokenReplayValidationError, ExceptionType: CustomSecurityTokenReplayDetectedException : SecurityTokenReplayDetectedException + theoryData.Add(new TokenReplayExtensibilityTheoryData( + "CustomTokenReplayValidatorCustomExceptionDelegate", + tokenHandlerType, + expirationTime, + CustomTokenReplayValidationDelegates.CustomTokenReplayValidatorCustomExceptionDelegate, + extraStackFrames: extraStackFrames) + { + ExpectedException = new ExpectedException( + typeof(CustomSecurityTokenReplayDetectedException), + nameof(CustomTokenReplayValidationDelegates.CustomTokenReplayValidatorCustomExceptionDelegate)), + ValidationError = new CustomTokenReplayValidationError( + new MessageDetail( + nameof(CustomTokenReplayValidationDelegates.CustomTokenReplayValidatorCustomExceptionDelegate), null), + ValidationFailureType.TokenReplayValidationFailed, + typeof(CustomSecurityTokenReplayDetectedException), + new StackFrame("CustomTokenReplayValidationDelegates.cs", 0), + expirationTime), + }); + + // CustomTokenReplayValidationError : TokenReplayValidationError, ExceptionType: NotSupportedException : SystemException + theoryData.Add(new TokenReplayExtensibilityTheoryData( + "CustomTokenReplayValidatorUnknownExceptionDelegate", + tokenHandlerType, + expirationTime, + CustomTokenReplayValidationDelegates.CustomTokenReplayValidatorUnknownExceptionDelegate, + extraStackFrames: extraStackFrames) + { + // CustomTokenReplayValidationError does not handle the exception type 'NotSupportedException' + ExpectedException = ExpectedException.SecurityTokenException( + LogHelper.FormatInvariant( + Tokens.LogMessages.IDX10002, // "IDX10002: Unknown exception type returned. Type: '{0}'. Message: '{1}'."; + typeof(NotSupportedException), + nameof(CustomTokenReplayValidationDelegates.CustomTokenReplayValidatorUnknownExceptionDelegate))), + ValidationError = new CustomTokenReplayValidationError( + new MessageDetail( + nameof(CustomTokenReplayValidationDelegates.CustomTokenReplayValidatorUnknownExceptionDelegate), null), + ValidationFailureType.TokenReplayValidationFailed, + typeof(NotSupportedException), + new StackFrame("CustomTokenReplayValidationDelegates.cs", 0), + expirationTime), + }); + + // CustomTokenReplayValidationError : TokenReplayValidationError, ExceptionType: NotSupportedException : SystemException, ValidationFailureType: CustomAudienceValidationFailureType + theoryData.Add(new TokenReplayExtensibilityTheoryData( + "CustomTokenReplayValidatorCustomExceptionCustomFailureTypeDelegate", + tokenHandlerType, + expirationTime, + CustomTokenReplayValidationDelegates.CustomTokenReplayValidatorCustomExceptionCustomFailureTypeDelegate, + extraStackFrames: extraStackFrames) + { + ExpectedException = new ExpectedException( + typeof(CustomSecurityTokenReplayDetectedException), + nameof(CustomTokenReplayValidationDelegates.CustomTokenReplayValidatorCustomExceptionCustomFailureTypeDelegate)), + ValidationError = new CustomTokenReplayValidationError( + new MessageDetail( + nameof(CustomTokenReplayValidationDelegates.CustomTokenReplayValidatorCustomExceptionCustomFailureTypeDelegate), null), + CustomTokenReplayValidationError.CustomTokenReplayValidationFailureType, + typeof(CustomSecurityTokenReplayDetectedException), + new StackFrame("CustomTokenReplayValidationDelegates.cs", 0), + expirationTime), + }); + #endregion + + #region return TokenReplayValidationError + // Test cases where delegate is overridden and return an TokenReplayValidationError + // TokenReplayValidationError : ValidationError, ExceptionType: SecurityTokenReplayDetectedException + theoryData.Add(new TokenReplayExtensibilityTheoryData( + "TokenReplayValidationDelegate", + tokenHandlerType, + expirationTime, + CustomTokenReplayValidationDelegates.TokenReplayValidationDelegate, + extraStackFrames: extraStackFrames) + { + ExpectedException = new ExpectedException( + typeof(SecurityTokenReplayDetectedException), + nameof(CustomTokenReplayValidationDelegates.TokenReplayValidationDelegate)), + ValidationError = new TokenReplayValidationError( + new MessageDetail( + nameof(CustomTokenReplayValidationDelegates.TokenReplayValidationDelegate), null), + ValidationFailureType.TokenReplayValidationFailed, + typeof(SecurityTokenReplayDetectedException), + new StackFrame("CustomTokenReplayValidationDelegates.cs", 0), + expirationTime) + }); + + // TokenReplayValidationError : ValidationError, ExceptionType: CustomSecurityTokenReplayDetectedException : SecurityTokenReplayDetectedException + theoryData.Add(new TokenReplayExtensibilityTheoryData( + "TokenReplayValidatorCustomTokenReplayDetectedExceptionTypeDelegate", + tokenHandlerType, + expirationTime, + CustomTokenReplayValidationDelegates.TokenReplayValidatorCustomTokenReplayDetectedExceptionTypeDelegate, + extraStackFrames: extraStackFrames) + { + // TokenReplayValidationError does not handle the exception type 'CustomSecurityTokenReplayDetectedException' + ExpectedException = ExpectedException.SecurityTokenException( + LogHelper.FormatInvariant( + Tokens.LogMessages.IDX10002, // "IDX10002: Unknown exception type returned. Type: '{0}'. Message: '{1}'."; + typeof(CustomSecurityTokenReplayDetectedException), + nameof(CustomTokenReplayValidationDelegates.TokenReplayValidatorCustomTokenReplayDetectedExceptionTypeDelegate))), + ValidationError = new TokenReplayValidationError( + new MessageDetail( + nameof(CustomTokenReplayValidationDelegates.TokenReplayValidatorCustomTokenReplayDetectedExceptionTypeDelegate), null), + ValidationFailureType.TokenReplayValidationFailed, + typeof(CustomSecurityTokenReplayDetectedException), + new StackFrame("CustomTokenReplayValidationDelegates.cs", 0), + expirationTime) + }); + + // TokenReplayValidationError : ValidationError, ExceptionType: CustomSecurityTokenException : SystemException + theoryData.Add(new TokenReplayExtensibilityTheoryData( + "TokenReplayValidatorCustomExceptionTypeDelegate", + tokenHandlerType, + expirationTime, + CustomTokenReplayValidationDelegates.TokenReplayValidatorCustomExceptionTypeDelegate, + extraStackFrames: extraStackFrames) + { + // TokenReplayValidationError does not handle the exception type 'CustomSecurityTokenException' + ExpectedException = ExpectedException.SecurityTokenException( + LogHelper.FormatInvariant( + Tokens.LogMessages.IDX10002, // "IDX10002: Unknown exception type returned. Type: '{0}'. Message: '{1}'."; + typeof(CustomSecurityTokenException), + nameof(CustomTokenReplayValidationDelegates.TokenReplayValidatorCustomExceptionTypeDelegate))), + ValidationError = new TokenReplayValidationError( + new MessageDetail( + nameof(CustomTokenReplayValidationDelegates.TokenReplayValidatorCustomExceptionTypeDelegate), null), + ValidationFailureType.TokenReplayValidationFailed, + typeof(CustomSecurityTokenException), + new StackFrame("CustomTokenReplayValidationDelegates.cs", 0), + expirationTime) + }); + + // TokenReplayValidationError : ValidationError, ExceptionType: SecurityTokenReplayDetectedException, inner: CustomSecurityTokenReplayDetectedException + theoryData.Add(new TokenReplayExtensibilityTheoryData( + "TokenReplayValidatorThrows", + tokenHandlerType, + expirationTime, + CustomTokenReplayValidationDelegates.TokenReplayValidatorThrows, + extraStackFrames: extraStackFrames - 1) + { + ExpectedException = new ExpectedException( + typeof(SecurityTokenReplayDetectedException), + string.Format(Tokens.LogMessages.IDX10276), + typeof(CustomSecurityTokenReplayDetectedException)), + ValidationError = new TokenReplayValidationError( + new MessageDetail( + string.Format(Tokens.LogMessages.IDX10276), null), + ValidationFailureType.TokenReplayValidatorThrew, + typeof(SecurityTokenReplayDetectedException), + new StackFrame(stackFrameFileName, 0), + expirationTime, + new SecurityTokenReplayDetectedException(nameof(CustomTokenReplayValidationDelegates.TokenReplayValidatorThrows)) + ) + }); + #endregion + + return theoryData; + } + } +} +#nullable restore diff --git a/test/Microsoft.IdentityModel.TestUtils/TokenValidationExtensibility/Tests/TokenReplayExtensibilityTheoryData.cs b/test/Microsoft.IdentityModel.TestUtils/TokenValidationExtensibility/Tests/TokenReplayExtensibilityTheoryData.cs new file mode 100644 index 0000000000..20f2111df6 --- /dev/null +++ b/test/Microsoft.IdentityModel.TestUtils/TokenValidationExtensibility/Tests/TokenReplayExtensibilityTheoryData.cs @@ -0,0 +1,31 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using Microsoft.IdentityModel.Tokens; + +#nullable enable +namespace Microsoft.IdentityModel.TestUtils.TokenValidationExtensibility.Tests +{ + public class TokenReplayExtensibilityTheoryData : ExtensibilityTheoryData + { + internal TokenReplayExtensibilityTheoryData( + string testId, + string tokenHandlerType, + DateTime expirationTime, + TokenReplayValidationDelegate tokenReplayValidationDelegate, + int extraStackFrames) : base(testId, tokenHandlerType, extraStackFrames) + { + SecurityTokenDescriptor = new() + { + Issuer = Default.Issuer, + IssuedAt = expirationTime.AddMinutes(-10), + NotBefore = expirationTime.AddMinutes(-5), + Expires = expirationTime, + }; + + ValidationParameters.TokenReplayValidator = tokenReplayValidationDelegate; + } + } +} +#nullable restore diff --git a/test/Microsoft.IdentityModel.TestUtils/TokenValidationExtensibility/Tests/TokenTypeExtensibilityTestCases.cs b/test/Microsoft.IdentityModel.TestUtils/TokenValidationExtensibility/Tests/TokenTypeExtensibilityTestCases.cs new file mode 100644 index 0000000000..1afd67a6dd --- /dev/null +++ b/test/Microsoft.IdentityModel.TestUtils/TokenValidationExtensibility/Tests/TokenTypeExtensibilityTestCases.cs @@ -0,0 +1,206 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Diagnostics; +using Xunit; +using Microsoft.IdentityModel.Tokens; +using Microsoft.IdentityModel.Logging; + +#nullable enable +namespace Microsoft.IdentityModel.TestUtils.TokenValidationExtensibility.Tests +{ + public partial class ExtensibilityTesting + { + public static TheoryData GenerateTokenTypeExtensibilityTestCases( + string tokenHandlerType, + int extraStackFrames, + string stackFrameFileName) + { + var theoryData = new TheoryData(); + CallContext callContext = new CallContext(); + string tokenType = "NOTJWT"; + + #region return CustomTokenTypeValidationError + // Test cases where delegate is overridden and return a CustomTokenTypeValidationError + // CustomTokenTypeValidationError : TokenTypeValidationError, ExceptionType: SecurityTokenInvalidTypeException + theoryData.Add(new TokenTypeExtensibilityTheoryData( + "CustomTokenTypeValidatorDelegate", + tokenHandlerType, + tokenType, + CustomTokenTypeValidationDelegates.CustomTokenTypeValidatorDelegate, + extraStackFrames: extraStackFrames) + { + ExpectedException = new ExpectedException( + typeof(SecurityTokenInvalidTypeException), + nameof(CustomTokenTypeValidationDelegates.CustomTokenTypeValidatorDelegate)), + ValidationError = new CustomTokenTypeValidationError( + new MessageDetail( + nameof(CustomTokenTypeValidationDelegates.CustomTokenTypeValidatorDelegate), null), + ValidationFailureType.TokenTypeValidationFailed, + typeof(SecurityTokenInvalidTypeException), + new StackFrame("CustomTokenTypeValidationDelegates.cs", 0), + tokenType) + }); + + // CustomTokenTypeValidationError : TokenTypeValidationError, ExceptionType: CustomSecurityTokenInvalidTypeException : SecurityTokenInvalidTypeException + theoryData.Add(new TokenTypeExtensibilityTheoryData( + "CustomTokenTypeValidatorCustomExceptionDelegate", + tokenHandlerType, + tokenType, + CustomTokenTypeValidationDelegates.CustomTokenTypeValidatorCustomExceptionDelegate, + extraStackFrames: extraStackFrames) + { + ExpectedException = new ExpectedException( + typeof(CustomSecurityTokenInvalidTypeException), + nameof(CustomTokenTypeValidationDelegates.CustomTokenTypeValidatorCustomExceptionDelegate)), + ValidationError = new CustomTokenTypeValidationError( + new MessageDetail( + nameof(CustomTokenTypeValidationDelegates.CustomTokenTypeValidatorCustomExceptionDelegate), null), + ValidationFailureType.TokenTypeValidationFailed, + typeof(CustomSecurityTokenInvalidTypeException), + new StackFrame("CustomTokenTypeValidationDelegates.cs", 0), + tokenType) + }); + + // CustomTokenTypeValidationError : TokenTypeValidationError, ExceptionType: NotSupportedException : SystemException + theoryData.Add(new TokenTypeExtensibilityTheoryData( + "CustomTokenTypeValidatorUnknownExceptionDelegate", + tokenHandlerType, + tokenType, + CustomTokenTypeValidationDelegates.CustomTokenTypeValidatorUnknownExceptionDelegate, + extraStackFrames: extraStackFrames) + { + // CustomTokenTypeValidationError does not handle the exception type 'NotSupportedException' + ExpectedException = ExpectedException.SecurityTokenException( + LogHelper.FormatInvariant( + Tokens.LogMessages.IDX10002, // "IDX10002: Unknown exception type returned. Type: '{0}'. Message: '{1}'."; + typeof(NotSupportedException), + nameof(CustomTokenTypeValidationDelegates.CustomTokenTypeValidatorUnknownExceptionDelegate))), + ValidationError = new CustomTokenTypeValidationError( + new MessageDetail( + nameof(CustomTokenTypeValidationDelegates.CustomTokenTypeValidatorUnknownExceptionDelegate), null), + ValidationFailureType.TokenTypeValidationFailed, + typeof(NotSupportedException), + new StackFrame("CustomTokenTypeValidationDelegates.cs", 0), + tokenType) + }); + + // CustomTokenTypeValidationError : TokenTypeValidationError, ExceptionType: NotSupportedException : SystemException, ValidationFailureType: CustomAudienceValidationFailureType + theoryData.Add(new TokenTypeExtensibilityTheoryData( + "CustomTokenTypeValidatorCustomExceptionCustomFailureTypeDelegate", + tokenHandlerType, + tokenType, + CustomTokenTypeValidationDelegates.CustomTokenTypeValidatorCustomExceptionCustomFailureTypeDelegate, + extraStackFrames: extraStackFrames) + { + ExpectedException = new ExpectedException( + typeof(CustomSecurityTokenInvalidTypeException), + nameof(CustomTokenTypeValidationDelegates.CustomTokenTypeValidatorCustomExceptionCustomFailureTypeDelegate)), + ValidationError = new CustomTokenTypeValidationError( + new MessageDetail( + nameof(CustomTokenTypeValidationDelegates.CustomTokenTypeValidatorCustomExceptionCustomFailureTypeDelegate), null), + CustomTokenTypeValidationError.CustomTokenTypeValidationFailureType, + typeof(CustomSecurityTokenInvalidTypeException), + new StackFrame("CustomTokenTypeValidationDelegates.cs", 0), + tokenType), + }); + #endregion + + #region return TokenTypeValidationError + // Test cases where delegate is overridden and return an TokenTypeValidationError + // TokenTypeValidationError : ValidationError, ExceptionType: SecurityTokenInvalidTypeException + theoryData.Add(new TokenTypeExtensibilityTheoryData( + "TokenTypeValidatorDelegate", + tokenHandlerType, + tokenType, + CustomTokenTypeValidationDelegates.TokenTypeValidatorDelegate, + extraStackFrames: extraStackFrames) + { + ExpectedException = new ExpectedException( + typeof(SecurityTokenInvalidTypeException), + nameof(CustomTokenTypeValidationDelegates.TokenTypeValidatorDelegate)), + ValidationError = new TokenTypeValidationError( + new MessageDetail( + nameof(CustomTokenTypeValidationDelegates.TokenTypeValidatorDelegate), null), + ValidationFailureType.TokenTypeValidationFailed, + typeof(SecurityTokenInvalidTypeException), + new StackFrame("CustomTokenTypeValidationDelegates.cs", 0), + tokenType) + }); + + // TokenTypeValidationError : ValidationError, ExceptionType: CustomSecurityTokenInvalidTypeException : SecurityTokenInvalidTypeException + theoryData.Add(new TokenTypeExtensibilityTheoryData( + "TokenTypeValidatorCustomTokenTypeExceptionTypeDelegate", + tokenHandlerType, + tokenType, + CustomTokenTypeValidationDelegates.TokenTypeValidatorCustomTokenTypeExceptionTypeDelegate, + extraStackFrames: extraStackFrames) + { + // TokenTypeValidationError does not handle the exception type 'CustomSecurityTokenInvalidTypeException' + ExpectedException = ExpectedException.SecurityTokenException( + LogHelper.FormatInvariant( + Tokens.LogMessages.IDX10002, // "IDX10002: Unknown exception type returned. Type: '{0}'. Message: '{1}'."; + typeof(CustomSecurityTokenInvalidTypeException), + nameof(CustomTokenTypeValidationDelegates.TokenTypeValidatorCustomTokenTypeExceptionTypeDelegate))), + ValidationError = new TokenTypeValidationError( + new MessageDetail( + nameof(CustomTokenTypeValidationDelegates.TokenTypeValidatorCustomTokenTypeExceptionTypeDelegate), null), + ValidationFailureType.TokenTypeValidationFailed, + typeof(CustomSecurityTokenInvalidTypeException), + new StackFrame("CustomTokenTypeValidationDelegates.cs", 0), + tokenType) + }); + + // TokenTypeValidationError : ValidationError, ExceptionType: CustomSecurityTokenException : SystemException + theoryData.Add(new TokenTypeExtensibilityTheoryData( + "TokenTypeValidatorCustomExceptionTypeDelegate", + tokenHandlerType, + tokenType, + CustomTokenTypeValidationDelegates.TokenTypeValidatorCustomExceptionTypeDelegate, + extraStackFrames: extraStackFrames) + { + // TokenTypeValidationError does not handle the exception type 'CustomSecurityTokenException' + ExpectedException = ExpectedException.SecurityTokenException( + LogHelper.FormatInvariant( + Tokens.LogMessages.IDX10002, // "IDX10002: Unknown exception type returned. Type: '{0}'. Message: '{1}'."; + typeof(CustomSecurityTokenException), + nameof(CustomTokenTypeValidationDelegates.TokenTypeValidatorCustomExceptionTypeDelegate))), + ValidationError = new TokenTypeValidationError( + new MessageDetail( + nameof(CustomTokenTypeValidationDelegates.TokenTypeValidatorCustomExceptionTypeDelegate), null), + ValidationFailureType.TokenTypeValidationFailed, + typeof(CustomSecurityTokenException), + new StackFrame("CustomTokenTypeValidationDelegates.cs", 0), + tokenType) + }); + + // TokenTypeValidationError : ValidationError, ExceptionType: SecurityTokenInvalidTypeException, inner: CustomSecurityTokenInvalidTypeException + theoryData.Add(new TokenTypeExtensibilityTheoryData( + "TokenTypeValidatorThrows", + tokenHandlerType, + tokenType, + CustomTokenTypeValidationDelegates.TokenTypeValidatorThrows, + extraStackFrames: extraStackFrames - 1) + { + ExpectedException = new ExpectedException( + typeof(SecurityTokenInvalidTypeException), + string.Format(Tokens.LogMessages.IDX10275), + typeof(CustomSecurityTokenInvalidTypeException)), + ValidationError = new TokenTypeValidationError( + new MessageDetail( + string.Format(Tokens.LogMessages.IDX10275), null), + ValidationFailureType.TokenTypeValidatorThrew, + typeof(SecurityTokenInvalidTypeException), + new StackFrame("JsonWebTokenHandler.ValidateToken.Internal.cs", 0), + tokenType, + new SecurityTokenInvalidTypeException(nameof(CustomTokenTypeValidationDelegates.TokenTypeValidatorThrows)) + ) + }); + #endregion + + return theoryData; + } + } +} +#nullable restore diff --git a/test/Microsoft.IdentityModel.TestUtils/TokenValidationExtensibility/Tests/TokenTypeExtensibilityTheoryData.cs b/test/Microsoft.IdentityModel.TestUtils/TokenValidationExtensibility/Tests/TokenTypeExtensibilityTheoryData.cs new file mode 100644 index 0000000000..c83ccdbd4f --- /dev/null +++ b/test/Microsoft.IdentityModel.TestUtils/TokenValidationExtensibility/Tests/TokenTypeExtensibilityTheoryData.cs @@ -0,0 +1,28 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using Microsoft.IdentityModel.Tokens; + +#nullable enable +namespace Microsoft.IdentityModel.TestUtils.TokenValidationExtensibility.Tests +{ + public class TokenTypeExtensibilityTheoryData : ExtensibilityTheoryData + { + internal TokenTypeExtensibilityTheoryData( + string testId, + string tokenHandlerType, + string tokenType, + TokenTypeValidationDelegate tokenTypeValidationDelegate, + int extraStackFrames) : base(testId, tokenHandlerType, extraStackFrames) + { + SecurityTokenDescriptor = new() + { + Issuer = Default.Issuer, + TokenType = tokenType, + }; + + ValidationParameters.TokenTypeValidator = tokenTypeValidationDelegate; + } + } +} +#nullable restore diff --git a/test/Microsoft.IdentityModel.TestUtils/TokenValidationExtensibility/Tests/ValidateTokenAsyncExtensibility.cs b/test/Microsoft.IdentityModel.TestUtils/TokenValidationExtensibility/Tests/ValidateTokenAsyncExtensibility.cs index f5cc14145e..240fd24e4a 100644 --- a/test/Microsoft.IdentityModel.TestUtils/TokenValidationExtensibility/Tests/ValidateTokenAsyncExtensibility.cs +++ b/test/Microsoft.IdentityModel.TestUtils/TokenValidationExtensibility/Tests/ValidateTokenAsyncExtensibility.cs @@ -7,6 +7,7 @@ using System.Threading.Tasks; using Microsoft.IdentityModel.Tokens; +#nullable enable namespace Microsoft.IdentityModel.TestUtils.TokenValidationExtensibility.Tests { public partial class ExtensibilityTesting @@ -35,8 +36,31 @@ public static async Task ValidateTokenAsync_Extensibility(ExtensibilityTheoryDat else { ValidationError validationError = validationResult.UnwrapError(); - IdentityComparer.AreValidationErrorsEqual(validationError, theoryData.ValidationError, context); + + if (validationError is SignatureValidationError signatureValidationError && + signatureValidationError.InnerValidationError is not null) + { + // Algorithm validation errors are wrapped in a signature validation error + // Other validation errors use the else branch. + IdentityComparer.AreValidationErrorsEqual( + signatureValidationError.InnerValidationError, + theoryData.ValidationError, + context); + } + else + { + IdentityComparer.AreValidationErrorsEqual( + validationError, + theoryData.ValidationError, + context); + } + theoryData.ExpectedException.ProcessException(validationError.GetException(), context); + + // In the algorithm validation case, we want to ensure the inner exception contains + // the expected message and not just assert its type. + if (theoryData.ExpectedInnerException is not null) + theoryData.ExpectedInnerException.ProcessException(validationError.GetException().InnerException, context); } } catch (Exception ex) @@ -48,3 +72,4 @@ public static async Task ValidateTokenAsync_Extensibility(ExtensibilityTheoryDat } } } +#nullable restore diff --git a/test/Microsoft.IdentityModel.Tokens.Saml.Tests/Saml2SecurityTokenHandler.Extensibility.Algorithm.cs b/test/Microsoft.IdentityModel.Tokens.Saml.Tests/Saml2SecurityTokenHandler.Extensibility.Algorithm.cs index b2e3171da4..4a11fc47ac 100644 --- a/test/Microsoft.IdentityModel.Tokens.Saml.Tests/Saml2SecurityTokenHandler.Extensibility.Algorithm.cs +++ b/test/Microsoft.IdentityModel.Tokens.Saml.Tests/Saml2SecurityTokenHandler.Extensibility.Algorithm.cs @@ -1,13 +1,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -using System; -using System.Diagnostics; -using System.Threading; using System.Threading.Tasks; -using Microsoft.IdentityModel.Logging; -using Microsoft.IdentityModel.TestUtils; - +using Microsoft.IdentityModel.TestUtils.TokenValidationExtensibility.Tests; using Xunit; #nullable enable @@ -15,322 +10,27 @@ namespace Microsoft.IdentityModel.Tokens.Saml2.Extensibility.Tests { public partial class Saml2SecurityTokenHandlerValidateTokenAsyncTests { - [Theory, MemberData(nameof(Algorithm_ExtensibilityTestCases), DisableDiscoveryEnumeration = true)] - public async Task ValidateTokenAsync_AlgorithmValidator_Extensibility(AlgorithmExtensibilityTheoryData theoryData) + [Theory, MemberData( + nameof(GenerateAlgorithmExtensibilityTestCases), + parameters: ["SAML2", 1], + DisableDiscoveryEnumeration = true)] + public async Task ValidateTokenAsync_AlgorithmValidator_Extensibility( + AlgorithmExtensibilityTheoryData theoryData) { - var context = TestUtilities.WriteHeader($"{this}.{nameof(ValidateTokenAsync_AlgorithmValidator_Extensibility)}", theoryData); - context.IgnoreType = false; - for (int i = 0; i < theoryData.ExtraStackFrames; i++) - theoryData.ValidationError!.AddStackFrame(new StackFrame(false)); - - Saml2SecurityToken saml2Token = (Saml2SecurityToken)theoryData.Saml2SecurityTokenHandler.CreateToken(new SecurityTokenDescriptor() - { - Issuer = Default.Issuer, - Subject = Default.SamlClaimsIdentity, - SigningCredentials = KeyingMaterial.DefaultX509SigningCreds_2048_RsaSha2_Sha2, - }); - theoryData.Saml2Token = theoryData.Saml2SecurityTokenHandler.ReadSaml2Token(saml2Token.Assertion.CanonicalString); - - theoryData.ValidationParameters!.IssuerSigningKeys.Add(theoryData.SigningKey); - - try - { - ValidationResult validationResult = await theoryData.Saml2SecurityTokenHandler.ValidateTokenAsync( - theoryData.Saml2Token!, - theoryData.ValidationParameters!, - theoryData.CallContext, - CancellationToken.None); - - if (validationResult.IsValid) - { - // We expect the validation to fail, but it passed - context.AddDiff("ValidationResult is Valid."); - } - else - { - ValidationError validationError = validationResult.UnwrapError(); - - if (validationError is SignatureValidationError signatureValidationError && - signatureValidationError.InnerValidationError is not null) - { - IdentityComparer.AreValidationErrorsEqual( - signatureValidationError.InnerValidationError, - theoryData.ValidationError, - context); - } - else - { - IdentityComparer.AreValidationErrorsEqual( - validationError, - theoryData.ValidationError, - context); - } - - var exception = validationError.GetException(); - theoryData.ExpectedException.ProcessException(exception, context); - // Process the inner exception since invalid algorithm exceptions are wrapped inside - // invalid signature exceptions - if (theoryData.ExpectedInnerException is not null) - theoryData.ExpectedInnerException.ProcessException(exception.InnerException, context); - } - } - catch (Exception ex) - { - // We expect the validation to fail, but it threw an exception - context.AddDiff($"ValidateTokenAsync threw exception: {ex}"); - } - - TestUtilities.AssertFailIfErrors(context); + await ExtensibilityTesting.ValidateTokenAsync_Extensibility( + theoryData, + this, + nameof(ValidateTokenAsync_AlgorithmValidator_Extensibility)); } - public static TheoryData Algorithm_ExtensibilityTestCases + public static TheoryData GenerateAlgorithmExtensibilityTestCases( + string tokenHandlerType, + int extraStackFrames) { - get - { - var theoryData = new TheoryData(); - CallContext callContext = new CallContext(); - var utcNow = DateTime.UtcNow; - var utcPlusOneHour = utcNow + TimeSpan.FromHours(1); - - #region return CustomAlgorithmValidationError - // Test cases where delegate is overridden and return a CustomAlgorithmValidationError - // CustomAlgorithmValidationError : AlgorithmValidationError, ExceptionType: SecurityTokenInvalidAlgorithmException - theoryData.Add(new AlgorithmExtensibilityTheoryData( - "CustomAlgorithmValidatorDelegate", - utcNow, - CustomAlgorithmValidationDelegates.CustomAlgorithmValidatorDelegate, - extraStackFrames: 1) - { - ExpectedException = new ExpectedException( - typeof(SecurityTokenInvalidSignatureException), - "IDX10518:", - typeof(SecurityTokenInvalidAlgorithmException)), - ExpectedInnerException = new ExpectedException( - typeof(SecurityTokenInvalidAlgorithmException), - nameof(CustomAlgorithmValidationDelegates.CustomAlgorithmValidatorDelegate)), - ValidationError = new CustomAlgorithmValidationError( - new MessageDetail( - nameof(CustomAlgorithmValidationDelegates.CustomAlgorithmValidatorDelegate), null), - ValidationFailureType.AlgorithmValidationFailed, - typeof(SecurityTokenInvalidAlgorithmException), - new StackFrame("CustomAlgorithmValidationDelegates.cs", 160), - "algorithm") - }); - - // CustomAlgorithmValidationError : AlgorithmValidationError, ExceptionType: CustomSecurityTokenInvalidAlgorithmException : SecurityTokenInvalidAlgorithmException - theoryData.Add(new AlgorithmExtensibilityTheoryData( - "CustomAlgorithmValidatorCustomExceptionDelegate", - utcNow, - CustomAlgorithmValidationDelegates.CustomAlgorithmValidatorCustomExceptionDelegate, - extraStackFrames: 1) - { - ExpectedException = new ExpectedException( - typeof(SecurityTokenInvalidSignatureException), - "IDX10518:", - typeof(CustomSecurityTokenInvalidAlgorithmException)), - ExpectedInnerException = new ExpectedException( - typeof(CustomSecurityTokenInvalidAlgorithmException), - nameof(CustomAlgorithmValidationDelegates.CustomAlgorithmValidatorCustomExceptionDelegate)), - ValidationError = new CustomAlgorithmValidationError( - new MessageDetail( - nameof(CustomAlgorithmValidationDelegates.CustomAlgorithmValidatorCustomExceptionDelegate), null), - ValidationFailureType.AlgorithmValidationFailed, - typeof(CustomSecurityTokenInvalidAlgorithmException), - new StackFrame("CustomAlgorithmValidationDelegates.cs", 175), - "algorithm"), - }); - - // CustomAlgorithmValidationError : AlgorithmValidationError, ExceptionType: NotSupportedException : SystemException - theoryData.Add(new AlgorithmExtensibilityTheoryData( - "CustomAlgorithmValidatorUnknownExceptionDelegate", - utcNow, - CustomAlgorithmValidationDelegates.CustomAlgorithmValidatorUnknownExceptionDelegate, - extraStackFrames: 1) - { - // CustomAlgorithmValidationError does not handle the exception type 'NotSupportedException' - ExpectedException = new ExpectedException( - typeof(SecurityTokenInvalidSignatureException), - "IDX10518:", - typeof(SecurityTokenException)), - ExpectedInnerException = ExpectedException.SecurityTokenException( - LogHelper.FormatInvariant( - Tokens.LogMessages.IDX10002, // "IDX10002: Unknown exception type returned. Type: '{0}'. Message: '{1}'."; - typeof(NotSupportedException), - nameof(CustomAlgorithmValidationDelegates.CustomAlgorithmValidatorUnknownExceptionDelegate))), - ValidationError = new CustomAlgorithmValidationError( - new MessageDetail( - nameof(CustomAlgorithmValidationDelegates.CustomAlgorithmValidatorUnknownExceptionDelegate), null), - ValidationFailureType.AlgorithmValidationFailed, - typeof(NotSupportedException), - new StackFrame("CustomAlgorithmValidationDelegates.cs", 205), - "algorithm"), - }); - - // CustomAlgorithmValidationError : AlgorithmValidationError, ExceptionType: NotSupportedException : SystemException, ValidationFailureType: CustomAudienceValidationFailureType - theoryData.Add(new AlgorithmExtensibilityTheoryData( - "CustomAlgorithmValidatorCustomExceptionCustomFailureTypeDelegate", - utcNow, - CustomAlgorithmValidationDelegates.CustomAlgorithmValidatorCustomExceptionCustomFailureTypeDelegate, - extraStackFrames: 1) - { - ExpectedException = new ExpectedException( - typeof(SecurityTokenInvalidSignatureException), - "IDX10518:", - typeof(CustomSecurityTokenInvalidAlgorithmException)), - ExpectedInnerException = new ExpectedException( - typeof(CustomSecurityTokenInvalidAlgorithmException), - nameof(CustomAlgorithmValidationDelegates.CustomAlgorithmValidatorCustomExceptionCustomFailureTypeDelegate)), - ValidationError = new CustomAlgorithmValidationError( - new MessageDetail( - nameof(CustomAlgorithmValidationDelegates.CustomAlgorithmValidatorCustomExceptionCustomFailureTypeDelegate), null), - CustomAlgorithmValidationError.CustomAlgorithmValidationFailureType, - typeof(CustomSecurityTokenInvalidAlgorithmException), - new StackFrame("CustomAlgorithmValidationDelegates.cs", 190), - "algorithm"), - }); - #endregion - - #region return AlgorithmValidationError - // Test cases where delegate is overridden and return an AlgorithmValidationError - // AlgorithmValidationError : ValidationError, ExceptionType: SecurityTokenInvalidAlgorithmException - theoryData.Add(new AlgorithmExtensibilityTheoryData( - "AlgorithmValidatorDelegate", - utcNow, - CustomAlgorithmValidationDelegates.AlgorithmValidatorDelegate, - extraStackFrames: 1) - { - ExpectedException = new ExpectedException( - typeof(SecurityTokenInvalidSignatureException), - "IDX10518:", - typeof(SecurityTokenInvalidAlgorithmException)), - ExpectedInnerException = new ExpectedException( - typeof(SecurityTokenInvalidAlgorithmException), - nameof(CustomAlgorithmValidationDelegates.AlgorithmValidatorDelegate)), - ValidationError = new AlgorithmValidationError( - new MessageDetail( - nameof(CustomAlgorithmValidationDelegates.AlgorithmValidatorDelegate), null), - ValidationFailureType.AlgorithmValidationFailed, - typeof(SecurityTokenInvalidAlgorithmException), - new StackFrame("CustomAlgorithmValidationDelegates.cs", 235), - "algorithm") - }); - - // AlgorithmValidationError : ValidationError, ExceptionType: CustomSecurityTokenInvalidAlgorithmException : SecurityTokenInvalidAlgorithmException - theoryData.Add(new AlgorithmExtensibilityTheoryData( - "AlgorithmValidatorCustomAlgorithmExceptionTypeDelegate", - utcNow, - CustomAlgorithmValidationDelegates.AlgorithmValidatorCustomAlgorithmExceptionTypeDelegate, - extraStackFrames: 1) - { - // AlgorithmValidationError does not handle the exception type 'CustomSecurityTokenInvalidAlgorithmException' - ExpectedException = new ExpectedException( - typeof(SecurityTokenInvalidSignatureException), - "IDX10518:", - typeof(SecurityTokenException)), - ExpectedInnerException = ExpectedException.SecurityTokenException( - LogHelper.FormatInvariant( - Tokens.LogMessages.IDX10002, // "IDX10002: Unknown exception type returned. Type: '{0}'. Message: '{1}'."; - typeof(CustomSecurityTokenInvalidAlgorithmException), - nameof(CustomAlgorithmValidationDelegates.AlgorithmValidatorCustomAlgorithmExceptionTypeDelegate))), - ValidationError = new AlgorithmValidationError( - new MessageDetail( - nameof(CustomAlgorithmValidationDelegates.AlgorithmValidatorCustomAlgorithmExceptionTypeDelegate), null), - ValidationFailureType.AlgorithmValidationFailed, - typeof(CustomSecurityTokenInvalidAlgorithmException), - new StackFrame("CustomAlgorithmValidationDelegates.cs", 259), - "algorithm") - }); - - // AlgorithmValidationError : ValidationError, ExceptionType: CustomSecurityTokenException : SystemException - theoryData.Add(new AlgorithmExtensibilityTheoryData( - "AlgorithmValidatorCustomExceptionTypeDelegate", - utcNow, - CustomAlgorithmValidationDelegates.AlgorithmValidatorCustomExceptionTypeDelegate, - extraStackFrames: 1) - { - // AlgorithmValidationError does not handle the exception type 'CustomSecurityTokenException' - ExpectedException = new ExpectedException( - typeof(SecurityTokenInvalidSignatureException), - "IDX10518:", - typeof(SecurityTokenException)), - ExpectedInnerException = ExpectedException.SecurityTokenException( - LogHelper.FormatInvariant( - Tokens.LogMessages.IDX10002, // "IDX10002: Unknown exception type returned. Type: '{0}'. Message: '{1}'."; - typeof(CustomSecurityTokenException), - nameof(CustomAlgorithmValidationDelegates.AlgorithmValidatorCustomExceptionTypeDelegate))), - ValidationError = new AlgorithmValidationError( - new MessageDetail( - nameof(CustomAlgorithmValidationDelegates.AlgorithmValidatorCustomExceptionTypeDelegate), null), - ValidationFailureType.AlgorithmValidationFailed, - typeof(CustomSecurityTokenException), - new StackFrame("CustomAlgorithmValidationDelegates.cs", 274), - "algorithm") - }); - - // SignatureValidationError : ValidationError, ExceptionType: SecurityTokenInvalidSignatureException, inner: CustomSecurityTokenInvalidAlgorithmException - theoryData.Add(new AlgorithmExtensibilityTheoryData( - "AlgorithmValidatorThrows", - utcNow, - CustomAlgorithmValidationDelegates.AlgorithmValidatorThrows, - extraStackFrames: 2) - { - ExpectedException = new ExpectedException( - typeof(SecurityTokenInvalidSignatureException), - "IDX10273:", - typeof(CustomSecurityTokenInvalidAlgorithmException)), - ExpectedInnerException = new ExpectedException( - typeof(CustomSecurityTokenInvalidAlgorithmException), - nameof(CustomAlgorithmValidationDelegates.AlgorithmValidatorThrows)), - ValidationError = new SignatureValidationError( - new MessageDetail( - string.Format(Tokens.LogMessages.IDX10273), null), - ValidationFailureType.AlgorithmValidatorThrew, - typeof(SecurityTokenInvalidSignatureException), - new StackFrame("Saml2SecurityTokenHandler.ValidateSignature.cs", 250), - null, // no inner validation error - new CustomSecurityTokenInvalidAlgorithmException(nameof(CustomAlgorithmValidationDelegates.AlgorithmValidatorThrows), null) - ) - }); - #endregion - - return theoryData; - } - } - - public class AlgorithmExtensibilityTheoryData : TheoryDataBase - { - internal AlgorithmExtensibilityTheoryData(string testId, DateTime utcNow, AlgorithmValidationDelegate algorithmValidator, int extraStackFrames) : base(testId) - { - ValidationParameters = new ValidationParameters - { - // We leave the default signature validator to call the custom algorithm validator - AlgorithmValidator = algorithmValidator, - AudienceValidator = SkipValidationDelegates.SkipAudienceValidation, - IssuerValidatorAsync = SkipValidationDelegates.SkipIssuerValidation, - IssuerSigningKeyValidator = SkipValidationDelegates.SkipIssuerSigningKeyValidation, - LifetimeValidator = SkipValidationDelegates.SkipLifetimeValidation, - TokenReplayValidator = SkipValidationDelegates.SkipTokenReplayValidation, - TokenTypeValidator = SkipValidationDelegates.SkipTokenTypeValidation, - }; - - ExtraStackFrames = extraStackFrames; - } - - public Saml2SecurityToken? Saml2Token { get; set; } - - public Saml2SecurityTokenHandler Saml2SecurityTokenHandler { get; } = new Saml2SecurityTokenHandler(); - - public bool IsValid { get; set; } - - internal ValidationError? ValidationError { get; set; } - - public ExpectedException? ExpectedInnerException { get; set; } - - internal int ExtraStackFrames { get; } - - internal ValidationParameters ValidationParameters { get; } - - public SecurityKey SigningKey { get; set; } = KeyingMaterial.DefaultX509SigningCreds_2048_RsaSha2_Sha2.Key; + return ExtensibilityTesting.GenerateAlgorithmExtensibilityTestCases( + tokenHandlerType, + extraStackFrames, + "Saml2SecurityTokenHandler.ValidateSignature.cs"); } } } diff --git a/test/Microsoft.IdentityModel.Tokens.Saml.Tests/Saml2SecurityTokenHandler.Extensibility.IssuerSigningKey.cs b/test/Microsoft.IdentityModel.Tokens.Saml.Tests/Saml2SecurityTokenHandler.Extensibility.IssuerSigningKey.cs index 95c1eecfd6..9bc70cdbb8 100644 --- a/test/Microsoft.IdentityModel.Tokens.Saml.Tests/Saml2SecurityTokenHandler.Extensibility.IssuerSigningKey.cs +++ b/test/Microsoft.IdentityModel.Tokens.Saml.Tests/Saml2SecurityTokenHandler.Extensibility.IssuerSigningKey.cs @@ -1,13 +1,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -using System; -using System.Diagnostics; -using System.Threading; using System.Threading.Tasks; -using Microsoft.IdentityModel.Logging; -using Microsoft.IdentityModel.TestUtils; - +using Microsoft.IdentityModel.TestUtils.TokenValidationExtensibility.Tests; using Xunit; #nullable enable @@ -15,268 +10,27 @@ namespace Microsoft.IdentityModel.Tokens.Saml2.Extensibility.Tests { public partial class Saml2SecurityTokenHandlerValidateTokenAsyncTests { - [Theory, MemberData(nameof(IssuerSigningKey_ExtensibilityTestCases), DisableDiscoveryEnumeration = true)] - public async Task ValidateTokenAsync_IssuerSigningKeyValidator_Extensibility(IssuerSigningKeyExtensibilityTheoryData theoryData) - { - var context = TestUtilities.WriteHeader($"{this}.{nameof(ValidateTokenAsync_IssuerSigningKeyValidator_Extensibility)}", theoryData); - context.IgnoreType = false; - for (int i = 0; i < theoryData.ExtraStackFrames; i++) - theoryData.IssuerSigningKeyValidationError!.AddStackFrame(new StackFrame(false)); - - try - { - ValidationResult validationResult = await theoryData.Saml2SecurityTokenHandler.ValidateTokenAsync( - theoryData.Saml2Token!, - theoryData.ValidationParameters!, - theoryData.CallContext, - CancellationToken.None); - - if (validationResult.IsValid) - { - context.AddDiff("validationResult.IsValid is true, expected false"); - } - else - { - ValidationError validationError = validationResult.UnwrapError(); - IdentityComparer.AreValidationErrorsEqual(validationError, theoryData.IssuerSigningKeyValidationError, context); - theoryData.ExpectedException.ProcessException(validationError.GetException(), context); - } - } - catch (Exception ex) - { - theoryData.ExpectedException.ProcessException(ex, context); - } - - TestUtilities.AssertFailIfErrors(context); - } - - public static TheoryData IssuerSigningKey_ExtensibilityTestCases + [Theory, MemberData( + nameof(GenerateIssuerSigningKeyExtensibilityTestCases), + parameters: ["SAML2", 1], + DisableDiscoveryEnumeration = true)] + public async Task ValidateTokenAsync_IssuerSigningKeyValidator_Extensibility( + IssuerSigningKeyExtensibilityTheoryData theoryData) { - get - { - var theoryData = new TheoryData(); - CallContext callContext = new CallContext(); - var utcNow = DateTime.UtcNow; - var utcPlusOneHour = utcNow + TimeSpan.FromHours(1); - - #region return CustomIssuerSigningKeyValidationError - // Test cases where delegate is overridden and return a CustomIssuerSigningKeyValidationError - // CustomIssuerSigningKeyValidationError : IssuerSigningKeyValidationError, ExceptionType: SecurityTokenInvalidIssuerSigningKeyException - theoryData.Add(new IssuerSigningKeyExtensibilityTheoryData( - "CustomIssuerSigningKeyValidatorDelegate", - utcNow, - CustomIssuerSigningKeyValidationDelegates.CustomIssuerSigningKeyValidatorDelegate, - extraStackFrames: 1) - { - ExpectedException = new ExpectedException( - typeof(SecurityTokenInvalidSigningKeyException), - nameof(CustomIssuerSigningKeyValidationDelegates.CustomIssuerSigningKeyValidatorDelegate)), - IssuerSigningKeyValidationError = new CustomIssuerSigningKeyValidationError( - new MessageDetail( - nameof(CustomIssuerSigningKeyValidationDelegates.CustomIssuerSigningKeyValidatorDelegate), null), - ValidationFailureType.SigningKeyValidationFailed, - typeof(SecurityTokenInvalidSigningKeyException), - new StackFrame("CustomIssuerSigningKeyValidationDelegates.cs", 160), - null) - }); - - // CustomIssuerSigningKeyValidationError : IssuerSigningKeyValidationError, ExceptionType: CustomSecurityTokenInvalidIssuerSigningKeyException : SecurityTokenInvalidIssuerSigningKeyException - theoryData.Add(new IssuerSigningKeyExtensibilityTheoryData( - "CustomIssuerSigningKeyValidatorCustomExceptionDelegate", - utcNow, - CustomIssuerSigningKeyValidationDelegates.CustomIssuerSigningKeyValidatorCustomExceptionDelegate, - extraStackFrames: 1) - { - ExpectedException = new ExpectedException( - typeof(CustomSecurityTokenInvalidSigningKeyException), - nameof(CustomIssuerSigningKeyValidationDelegates.CustomIssuerSigningKeyValidatorCustomExceptionDelegate)), - IssuerSigningKeyValidationError = new CustomIssuerSigningKeyValidationError( - new MessageDetail( - nameof(CustomIssuerSigningKeyValidationDelegates.CustomIssuerSigningKeyValidatorCustomExceptionDelegate), null), - ValidationFailureType.SigningKeyValidationFailed, - typeof(CustomSecurityTokenInvalidSigningKeyException), - new StackFrame("CustomIssuerSigningKeyValidationDelegates.cs", 175), - null) - }); - - // CustomIssuerSigningKeyValidationError : IssuerSigningKeyValidationError, ExceptionType: NotSupportedException : SystemException - theoryData.Add(new IssuerSigningKeyExtensibilityTheoryData( - "CustomIssuerSigningKeyValidatorUnknownExceptionDelegate", - utcNow, - CustomIssuerSigningKeyValidationDelegates.CustomIssuerSigningKeyValidatorUnknownExceptionDelegate, - extraStackFrames: 1) - { - // CustomIssuerSigningKeyValidationError does not handle the exception type 'NotSupportedException' - ExpectedException = ExpectedException.SecurityTokenException( - LogHelper.FormatInvariant( - Tokens.LogMessages.IDX10002, // "IDX10002: Unknown exception type returned. Type: '{0}'. Message: '{1}'."; - typeof(NotSupportedException), - nameof(CustomIssuerSigningKeyValidationDelegates.CustomIssuerSigningKeyValidatorUnknownExceptionDelegate))), - IssuerSigningKeyValidationError = new CustomIssuerSigningKeyValidationError( - new MessageDetail( - nameof(CustomIssuerSigningKeyValidationDelegates.CustomIssuerSigningKeyValidatorUnknownExceptionDelegate), null), - ValidationFailureType.SigningKeyValidationFailed, - typeof(NotSupportedException), - new StackFrame("CustomIssuerSigningKeyValidationDelegates.cs", 205), - null) - }); - - // CustomIssuerSigningKeyValidationError : IssuerSigningKeyValidationError, ExceptionType: NotSupportedException : SystemException, ValidationFailureType: CustomAudienceValidationFailureType - theoryData.Add(new IssuerSigningKeyExtensibilityTheoryData( - "CustomIssuerSigningKeyValidatorCustomExceptionCustomFailureTypeDelegate", - utcNow, - CustomIssuerSigningKeyValidationDelegates.CustomIssuerSigningKeyValidatorCustomExceptionCustomFailureTypeDelegate, - extraStackFrames: 1) - { - ExpectedException = new ExpectedException( - typeof(CustomSecurityTokenInvalidSigningKeyException), - nameof(CustomIssuerSigningKeyValidationDelegates.CustomIssuerSigningKeyValidatorCustomExceptionCustomFailureTypeDelegate)), - IssuerSigningKeyValidationError = new CustomIssuerSigningKeyValidationError( - new MessageDetail( - nameof(CustomIssuerSigningKeyValidationDelegates.CustomIssuerSigningKeyValidatorCustomExceptionCustomFailureTypeDelegate), null), - CustomIssuerSigningKeyValidationError.CustomIssuerSigningKeyValidationFailureType, - typeof(CustomSecurityTokenInvalidSigningKeyException), - new StackFrame("CustomIssuerSigningKeyValidationDelegates.cs", 190), - null), - }); - #endregion - - #region return IssuerSigningKeyValidationError - // Test cases where delegate is overridden and return an IssuerSigningKeyValidationError - // IssuerSigningKeyValidationError : ValidationError, ExceptionType: SecurityTokenInvalidIssuerSigningKeyException - theoryData.Add(new IssuerSigningKeyExtensibilityTheoryData( - "IssuerSigningKeyValidatorDelegate", - utcNow, - CustomIssuerSigningKeyValidationDelegates.IssuerSigningKeyValidatorDelegate, - extraStackFrames: 1) - { - ExpectedException = new ExpectedException( - typeof(SecurityTokenInvalidSigningKeyException), - nameof(CustomIssuerSigningKeyValidationDelegates.IssuerSigningKeyValidatorDelegate)), - IssuerSigningKeyValidationError = new IssuerSigningKeyValidationError( - new MessageDetail( - nameof(CustomIssuerSigningKeyValidationDelegates.IssuerSigningKeyValidatorDelegate), null), - ValidationFailureType.SigningKeyValidationFailed, - typeof(SecurityTokenInvalidSigningKeyException), - new StackFrame("CustomIssuerSigningKeyValidationDelegates.cs", 235), - null) - }); - - // IssuerSigningKeyValidationError : ValidationError, ExceptionType: CustomSecurityTokenInvalidIssuerSigningKeyException : SecurityTokenInvalidIssuerSigningKeyException - theoryData.Add(new IssuerSigningKeyExtensibilityTheoryData( - "IssuerSigningKeyValidatorCustomIssuerSigningKeyExceptionTypeDelegate", - utcNow, - CustomIssuerSigningKeyValidationDelegates.IssuerSigningKeyValidatorCustomIssuerSigningKeyExceptionTypeDelegate, - extraStackFrames: 1) - { - // IssuerSigningKeyValidationError does not handle the exception type 'CustomSecurityTokenInvalidIssuerSigningKeyException' - ExpectedException = ExpectedException.SecurityTokenException( - LogHelper.FormatInvariant( - Tokens.LogMessages.IDX10002, // "IDX10002: Unknown exception type returned. Type: '{0}'. Message: '{1}'."; - typeof(CustomSecurityTokenInvalidSigningKeyException), - nameof(CustomIssuerSigningKeyValidationDelegates.IssuerSigningKeyValidatorCustomIssuerSigningKeyExceptionTypeDelegate))), - IssuerSigningKeyValidationError = new IssuerSigningKeyValidationError( - new MessageDetail( - nameof(CustomIssuerSigningKeyValidationDelegates.IssuerSigningKeyValidatorCustomIssuerSigningKeyExceptionTypeDelegate), null), - ValidationFailureType.SigningKeyValidationFailed, - typeof(CustomSecurityTokenInvalidSigningKeyException), - new StackFrame("CustomIssuerSigningKeyValidationDelegates.cs", 259), - null) - }); - - // IssuerSigningKeyValidationError : ValidationError, ExceptionType: CustomSecurityTokenException : SystemException - theoryData.Add(new IssuerSigningKeyExtensibilityTheoryData( - "IssuerSigningKeyValidatorCustomExceptionTypeDelegate", - utcNow, - CustomIssuerSigningKeyValidationDelegates.IssuerSigningKeyValidatorCustomExceptionTypeDelegate, - extraStackFrames: 1) - { - // IssuerSigningKeyValidationError does not handle the exception type 'CustomSecurityTokenException' - ExpectedException = ExpectedException.SecurityTokenException( - LogHelper.FormatInvariant( - Tokens.LogMessages.IDX10002, // "IDX10002: Unknown exception type returned. Type: '{0}'. Message: '{1}'."; - typeof(CustomSecurityTokenException), - nameof(CustomIssuerSigningKeyValidationDelegates.IssuerSigningKeyValidatorCustomExceptionTypeDelegate))), - IssuerSigningKeyValidationError = new IssuerSigningKeyValidationError( - new MessageDetail( - nameof(CustomIssuerSigningKeyValidationDelegates.IssuerSigningKeyValidatorCustomExceptionTypeDelegate), null), - ValidationFailureType.SigningKeyValidationFailed, - typeof(CustomSecurityTokenException), - new StackFrame("CustomIssuerSigningKeyValidationDelegates.cs", 274), - null) - }); - - // IssuerSigningKeyValidationError : ValidationError, ExceptionType: SecurityTokenInvalidIssuerSigningKeyException, inner: CustomSecurityTokenInvalidIssuerSigningKeyException - theoryData.Add(new IssuerSigningKeyExtensibilityTheoryData( - "IssuerSigningKeyValidatorThrows", - utcNow, - CustomIssuerSigningKeyValidationDelegates.IssuerSigningKeyValidatorThrows, - extraStackFrames: 0) - { - ExpectedException = new ExpectedException( - typeof(SecurityTokenInvalidSigningKeyException), - string.Format(Tokens.LogMessages.IDX10274), - typeof(CustomSecurityTokenInvalidSigningKeyException)), - IssuerSigningKeyValidationError = new IssuerSigningKeyValidationError( - new MessageDetail( - string.Format(Tokens.LogMessages.IDX10274), null), - ValidationFailureType.IssuerSigningKeyValidatorThrew, - typeof(SecurityTokenInvalidSigningKeyException), - new StackFrame("Saml2SecurityTokenHandler.ValidateToken.Internal.cs", 250), - null, - new SecurityTokenInvalidSigningKeyException(nameof(CustomIssuerSigningKeyValidationDelegates.IssuerSigningKeyValidatorThrows)) - ) - }); - #endregion - - return theoryData; - } + await ExtensibilityTesting.ValidateTokenAsync_Extensibility( + theoryData, + this, + nameof(ValidateTokenAsync_IssuerSigningKeyValidator_Extensibility)); } - public class IssuerSigningKeyExtensibilityTheoryData : TheoryDataBase + public static TheoryData GenerateIssuerSigningKeyExtensibilityTestCases( + string tokenHandlerType, + int extraStackFrames) { - internal IssuerSigningKeyExtensibilityTheoryData(string testId, DateTime utcNow, IssuerSigningKeyValidationDelegate issuerSigningKeyValidator, int extraStackFrames) : base(testId) - { - Saml2Token = (Saml2SecurityToken)Saml2SecurityTokenHandler.CreateToken( - new SecurityTokenDescriptor() - { - Subject = Default.SamlClaimsIdentity, - Issuer = Default.Issuer, - }); - - ValidationParameters = new ValidationParameters - { - AlgorithmValidator = SkipValidationDelegates.SkipAlgorithmValidation, - AudienceValidator = SkipValidationDelegates.SkipAudienceValidation, - IssuerValidatorAsync = SkipValidationDelegates.SkipIssuerValidation, - IssuerSigningKeyValidator = issuerSigningKeyValidator, - LifetimeValidator = SkipValidationDelegates.SkipLifetimeValidation, - SignatureValidator = (SecurityToken token, ValidationParameters validationParameters, BaseConfiguration? configuration, CallContext callContext) => - { - token.SigningKey = SigningKey; - - return SigningKey; - }, - TokenReplayValidator = SkipValidationDelegates.SkipTokenReplayValidation, - TokenTypeValidator = SkipValidationDelegates.SkipTokenTypeValidation - }; - - ExtraStackFrames = extraStackFrames; - } - - public Saml2SecurityToken Saml2Token { get; } - - public Saml2SecurityTokenHandler Saml2SecurityTokenHandler { get; } = new Saml2SecurityTokenHandler(); - - public bool IsValid { get; set; } - - public SecurityKey SigningKey { get; set; } = KeyingMaterial.DefaultX509SigningCreds_2048_RsaSha2_Sha2.Key; - - internal ValidationParameters? ValidationParameters { get; set; } - - internal IssuerSigningKeyValidationError? IssuerSigningKeyValidationError { get; set; } - - internal int ExtraStackFrames { get; } + return ExtensibilityTesting.GenerateIssuerSigningKeyExtensibilityTestCases( + tokenHandlerType, + extraStackFrames, + "Saml2SecurityTokenHandler.ValidateToken.Internal.cs"); } } } diff --git a/test/Microsoft.IdentityModel.Tokens.Saml.Tests/Saml2SecurityTokenHandler.Extensibility.Signature.cs b/test/Microsoft.IdentityModel.Tokens.Saml.Tests/Saml2SecurityTokenHandler.Extensibility.Signature.cs index d1635c6635..7f39a236ca 100644 --- a/test/Microsoft.IdentityModel.Tokens.Saml.Tests/Saml2SecurityTokenHandler.Extensibility.Signature.cs +++ b/test/Microsoft.IdentityModel.Tokens.Saml.Tests/Saml2SecurityTokenHandler.Extensibility.Signature.cs @@ -1,13 +1,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -using System; -using System.Diagnostics; -using System.Threading; using System.Threading.Tasks; -using Microsoft.IdentityModel.Logging; -using Microsoft.IdentityModel.TestUtils; - +using Microsoft.IdentityModel.TestUtils.TokenValidationExtensibility.Tests; using Xunit; #nullable enable @@ -15,255 +10,27 @@ namespace Microsoft.IdentityModel.Tokens.Saml2.Extensibility.Tests { public partial class Saml2SecurityTokenHandlerValidateTokenAsyncTests { - [Theory, MemberData(nameof(Signature_ExtensibilityTestCases), DisableDiscoveryEnumeration = true)] - public async Task ValidateTokenAsync_SignatureValidator_Extensibility(SignatureExtensibilityTheoryData theoryData) - { - var context = TestUtilities.WriteHeader($"{this}.{nameof(ValidateTokenAsync_SignatureValidator_Extensibility)}", theoryData); - context.IgnoreType = false; - for (int i = 0; i < theoryData.ExtraStackFrames; i++) - theoryData.SignatureValidationError!.AddStackFrame(new StackFrame(false)); - - try - { - ValidationResult validationResult = await theoryData.Saml2SecurityTokenHandler.ValidateTokenAsync( - theoryData.Saml2Token!, - theoryData.ValidationParameters!, - theoryData.CallContext, - CancellationToken.None); - - if (validationResult.IsValid) - { - // We expect the validation to fail, but it passed - context.AddDiff("ValidationResult is Valid."); - } - else - { - ValidationError validationError = validationResult.UnwrapError(); - IdentityComparer.AreValidationErrorsEqual(validationError, theoryData.SignatureValidationError, context); - theoryData.ExpectedException.ProcessException(validationError.GetException(), context); - } - } - catch (Exception ex) - { - theoryData.ExpectedException.ProcessException(ex, context); - } - - TestUtilities.AssertFailIfErrors(context); - } - - public static TheoryData Signature_ExtensibilityTestCases + [Theory, MemberData( + nameof(GenerateSignatureExtensibilityTestCases), + parameters: ["SAML2", 2], + DisableDiscoveryEnumeration = true)] + public async Task ValidateTokenAsync_SignatureValidator_Extensibility( + SignatureExtensibilityTheoryData theoryData) { - get - { - var theoryData = new TheoryData(); - CallContext callContext = new CallContext(); - var utcNow = DateTime.UtcNow; - var utcPlusOneHour = utcNow + TimeSpan.FromHours(1); - - #region return CustomSignatureValidationError - // Test cases where delegate is overridden and return a CustomSignatureValidationError - // CustomSignatureValidationError : SignatureValidationError, ExceptionType: SecurityTokenInvalidSignatureException - theoryData.Add(new SignatureExtensibilityTheoryData( - "CustomSignatureValidatorDelegate", - utcNow, - CustomSignatureValidationDelegates.CustomSignatureValidatorDelegate, - extraStackFrames: 2) - { - ExpectedException = new ExpectedException( - typeof(SecurityTokenInvalidSignatureException), - nameof(CustomSignatureValidationDelegates.CustomSignatureValidatorDelegate)), - SignatureValidationError = new CustomSignatureValidationError( - new MessageDetail( - nameof(CustomSignatureValidationDelegates.CustomSignatureValidatorDelegate), null), - ValidationFailureType.SignatureValidationFailed, - typeof(SecurityTokenInvalidSignatureException), - new StackFrame("CustomSignatureValidationDelegates.cs", 160)) - }); - - // CustomSignatureValidationError : SignatureValidationError, ExceptionType: CustomSecurityTokenInvalidSignatureException : SecurityTokenInvalidSignatureException - theoryData.Add(new SignatureExtensibilityTheoryData( - "CustomSignatureValidatorCustomExceptionDelegate", - utcNow, - CustomSignatureValidationDelegates.CustomSignatureValidatorCustomExceptionDelegate, - extraStackFrames: 2) - { - ExpectedException = new ExpectedException( - typeof(CustomSecurityTokenInvalidSignatureException), - nameof(CustomSignatureValidationDelegates.CustomSignatureValidatorCustomExceptionDelegate)), - SignatureValidationError = new CustomSignatureValidationError( - new MessageDetail( - nameof(CustomSignatureValidationDelegates.CustomSignatureValidatorCustomExceptionDelegate), null), - ValidationFailureType.SignatureValidationFailed, - typeof(CustomSecurityTokenInvalidSignatureException), - new StackFrame("CustomSignatureValidationDelegates.cs", 175)), - }); - - // CustomSignatureValidationError : SignatureValidationError, ExceptionType: NotSupportedException : SystemException - theoryData.Add(new SignatureExtensibilityTheoryData( - "CustomSignatureValidatorUnknownExceptionDelegate", - utcNow, - CustomSignatureValidationDelegates.CustomSignatureValidatorUnknownExceptionDelegate, - extraStackFrames: 2) - { - // CustomSignatureValidationError does not handle the exception type 'NotSupportedException' - ExpectedException = ExpectedException.SecurityTokenException( - LogHelper.FormatInvariant( - Tokens.LogMessages.IDX10002, // "IDX10002: Unknown exception type returned. Type: '{0}'. Message: '{1}'."; - typeof(NotSupportedException), - nameof(CustomSignatureValidationDelegates.CustomSignatureValidatorUnknownExceptionDelegate))), - SignatureValidationError = new CustomSignatureValidationError( - new MessageDetail( - nameof(CustomSignatureValidationDelegates.CustomSignatureValidatorUnknownExceptionDelegate), null), - ValidationFailureType.SignatureValidationFailed, - typeof(NotSupportedException), - new StackFrame("CustomSignatureValidationDelegates.cs", 205)), - }); - - // CustomSignatureValidationError : SignatureValidationError, ExceptionType: NotSupportedException : SystemException, ValidationFailureType: CustomAudienceValidationFailureType - theoryData.Add(new SignatureExtensibilityTheoryData( - "CustomSignatureValidatorCustomExceptionCustomFailureTypeDelegate", - utcNow, - CustomSignatureValidationDelegates.CustomSignatureValidatorCustomExceptionCustomFailureTypeDelegate, - extraStackFrames: 2) - { - ExpectedException = new ExpectedException( - typeof(CustomSecurityTokenInvalidSignatureException), - nameof(CustomSignatureValidationDelegates.CustomSignatureValidatorCustomExceptionCustomFailureTypeDelegate)), - SignatureValidationError = new CustomSignatureValidationError( - new MessageDetail( - nameof(CustomSignatureValidationDelegates.CustomSignatureValidatorCustomExceptionCustomFailureTypeDelegate), null), - CustomSignatureValidationError.CustomSignatureValidationFailureType, - typeof(CustomSecurityTokenInvalidSignatureException), - new StackFrame("CustomSignatureValidationDelegates.cs", 190)), - }); - #endregion - - #region return SignatureValidationError - // Test cases where delegate is overridden and return an SignatureValidationError - // SignatureValidationError : ValidationError, ExceptionType: SecurityTokenInvalidSignatureException - theoryData.Add(new SignatureExtensibilityTheoryData( - "SignatureValidatorDelegate", - utcNow, - CustomSignatureValidationDelegates.SignatureValidatorDelegate, - extraStackFrames: 2) - { - ExpectedException = new ExpectedException( - typeof(SecurityTokenInvalidSignatureException), - nameof(CustomSignatureValidationDelegates.SignatureValidatorDelegate)), - SignatureValidationError = new SignatureValidationError( - new MessageDetail( - nameof(CustomSignatureValidationDelegates.SignatureValidatorDelegate), null), - ValidationFailureType.SignatureValidationFailed, - typeof(SecurityTokenInvalidSignatureException), - new StackFrame("CustomSignatureValidationDelegates.cs", 235)) - }); - - // SignatureValidationError : ValidationError, ExceptionType: CustomSecurityTokenInvalidSignatureException : SecurityTokenInvalidSignatureException - theoryData.Add(new SignatureExtensibilityTheoryData( - "SignatureValidatorCustomSignatureExceptionTypeDelegate", - utcNow, - CustomSignatureValidationDelegates.SignatureValidatorCustomSignatureExceptionTypeDelegate, - extraStackFrames: 2) - { - // SignatureValidationError does not handle the exception type 'CustomSecurityTokenInvalidSignatureException' - ExpectedException = ExpectedException.SecurityTokenException( - LogHelper.FormatInvariant( - Tokens.LogMessages.IDX10002, // "IDX10002: Unknown exception type returned. Type: '{0}'. Message: '{1}'."; - typeof(CustomSecurityTokenInvalidSignatureException), - nameof(CustomSignatureValidationDelegates.SignatureValidatorCustomSignatureExceptionTypeDelegate))), - SignatureValidationError = new SignatureValidationError( - new MessageDetail( - nameof(CustomSignatureValidationDelegates.SignatureValidatorCustomSignatureExceptionTypeDelegate), null), - ValidationFailureType.SignatureValidationFailed, - typeof(CustomSecurityTokenInvalidSignatureException), - new StackFrame("CustomSignatureValidationDelegates.cs", 259)) - }); - - // SignatureValidationError : ValidationError, ExceptionType: CustomSecurityTokenException : SystemException - theoryData.Add(new SignatureExtensibilityTheoryData( - "SignatureValidatorCustomExceptionTypeDelegate", - utcNow, - CustomSignatureValidationDelegates.SignatureValidatorCustomExceptionTypeDelegate, - extraStackFrames: 2) - { - // SignatureValidationError does not handle the exception type 'CustomSecurityTokenException' - ExpectedException = ExpectedException.SecurityTokenException( - LogHelper.FormatInvariant( - Tokens.LogMessages.IDX10002, // "IDX10002: Unknown exception type returned. Type: '{0}'. Message: '{1}'."; - typeof(CustomSecurityTokenException), - nameof(CustomSignatureValidationDelegates.SignatureValidatorCustomExceptionTypeDelegate))), - SignatureValidationError = new SignatureValidationError( - new MessageDetail( - nameof(CustomSignatureValidationDelegates.SignatureValidatorCustomExceptionTypeDelegate), null), - ValidationFailureType.SignatureValidationFailed, - typeof(CustomSecurityTokenException), - new StackFrame("CustomSignatureValidationDelegates.cs", 274)) - }); - - // SignatureValidationError : ValidationError, ExceptionType: SecurityTokenInvalidSignatureException, inner: CustomSecurityTokenInvalidSignatureException - theoryData.Add(new SignatureExtensibilityTheoryData( - "SignatureValidatorThrows", - utcNow, - CustomSignatureValidationDelegates.SignatureValidatorThrows, - extraStackFrames: 1) - { - ExpectedException = new ExpectedException( - typeof(SecurityTokenInvalidSignatureException), - string.Format(Tokens.LogMessages.IDX10272), - typeof(CustomSecurityTokenInvalidSignatureException)), - SignatureValidationError = new SignatureValidationError( - new MessageDetail( - string.Format(Tokens.LogMessages.IDX10272), null), - ValidationFailureType.SignatureValidatorThrew, - typeof(SecurityTokenInvalidSignatureException), - new StackFrame("Saml2SecurityTokenHandler.ValidateSignature.cs", 250), - null, // no inner validation error - new SecurityTokenInvalidSignatureException(nameof(CustomSignatureValidationDelegates.SignatureValidatorThrows)) - ) - }); - #endregion - - return theoryData; - } + await ExtensibilityTesting.ValidateTokenAsync_Extensibility( + theoryData, + this, + nameof(ValidateTokenAsync_SignatureValidator_Extensibility)); } - public class SignatureExtensibilityTheoryData : TheoryDataBase + public static TheoryData GenerateSignatureExtensibilityTestCases( + string tokenHandlerType, + int extraStackFrames) { - internal SignatureExtensibilityTheoryData(string testId, DateTime utcNow, SignatureValidationDelegate signatureValidator, int extraStackFrames) : base(testId) - { - Saml2Token = (Saml2SecurityToken)Saml2SecurityTokenHandler.CreateToken( - new SecurityTokenDescriptor() - { - Subject = Default.SamlClaimsIdentity, - Issuer = Default.Issuer, - }); - - ValidationParameters = new ValidationParameters - { - AlgorithmValidator = SkipValidationDelegates.SkipAlgorithmValidation, - AudienceValidator = SkipValidationDelegates.SkipAudienceValidation, - IssuerValidatorAsync = SkipValidationDelegates.SkipIssuerValidation, - IssuerSigningKeyValidator = SkipValidationDelegates.SkipIssuerSigningKeyValidation, - LifetimeValidator = SkipValidationDelegates.SkipLifetimeValidation, - SignatureValidator = signatureValidator, - TokenReplayValidator = SkipValidationDelegates.SkipTokenReplayValidation, - TokenTypeValidator = SkipValidationDelegates.SkipTokenTypeValidation - }; - - ExtraStackFrames = extraStackFrames; - } - - public Saml2SecurityToken Saml2Token { get; } - - public Saml2SecurityTokenHandler Saml2SecurityTokenHandler { get; } = new Saml2SecurityTokenHandler(); - - public bool IsValid { get; set; } - - internal ValidationParameters ValidationParameters { get; } - - internal SignatureValidationError? SignatureValidationError { get; set; } - - internal int ExtraStackFrames { get; } + return ExtensibilityTesting.GenerateSignatureExtensibilityTestCases( + tokenHandlerType, + extraStackFrames, + "Saml2SecurityTokenHandler.ValidateSignature.cs"); } } } diff --git a/test/Microsoft.IdentityModel.Tokens.Saml.Tests/Saml2SecurityTokenHandler.Extensibility.TokenReplay.cs b/test/Microsoft.IdentityModel.Tokens.Saml.Tests/Saml2SecurityTokenHandler.Extensibility.TokenReplay.cs index 3266a4595a..8e801b04a9 100644 --- a/test/Microsoft.IdentityModel.Tokens.Saml.Tests/Saml2SecurityTokenHandler.Extensibility.TokenReplay.cs +++ b/test/Microsoft.IdentityModel.Tokens.Saml.Tests/Saml2SecurityTokenHandler.Extensibility.TokenReplay.cs @@ -1,13 +1,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -using System; -using System.Diagnostics; -using System.Threading; using System.Threading.Tasks; -using Microsoft.IdentityModel.Logging; -using Microsoft.IdentityModel.TestUtils; - +using Microsoft.IdentityModel.TestUtils.TokenValidationExtensibility.Tests; using Xunit; #nullable enable @@ -15,264 +10,27 @@ namespace Microsoft.IdentityModel.Tokens.Saml2.Extensibility.Tests { public partial class Saml2SecurityTokenHandlerValidateTokenAsyncTests { - [Theory, MemberData(nameof(TokenReplay_ExtensibilityTestCases), DisableDiscoveryEnumeration = true)] - public async Task ValidateTokenAsync_TokenReplayValidator_Extensibility(TokenReplayExtensibilityTheoryData theoryData) - { - var context = TestUtilities.WriteHeader($"{this}.{nameof(ValidateTokenAsync_TokenReplayValidator_Extensibility)}", theoryData); - context.IgnoreType = false; - for (int i = 0; i < theoryData.ExtraStackFrames; i++) - theoryData.TokenReplayValidationError!.AddStackFrame(new StackFrame(false)); - - try - { - ValidationResult validationResult = await theoryData.Saml2SecurityTokenHandler.ValidateTokenAsync( - theoryData.Saml2Token!, - theoryData.ValidationParameters!, - theoryData.CallContext, - CancellationToken.None); - - if (validationResult.IsValid) - { - context.Diffs.Add("validationResult.IsValid is true, expected false"); - } - else - { - ValidationError validationError = validationResult.UnwrapError(); - IdentityComparer.AreValidationErrorsEqual(validationError, theoryData.TokenReplayValidationError, context); - theoryData.ExpectedException.ProcessException(validationError.GetException(), context); - } - } - catch (Exception ex) - { - theoryData.ExpectedException.ProcessException(ex, context); - } - - TestUtilities.AssertFailIfErrors(context); - } - - public static TheoryData TokenReplay_ExtensibilityTestCases + [Theory, MemberData( + nameof(GenerateTokenReplayExtensibilityTestCases), + parameters: ["SAML2", 1], + DisableDiscoveryEnumeration = true)] + public async Task ValidateTokenAsync_TokenReplayValidator_Extensibility( + TokenReplayExtensibilityTheoryData theoryData) { - get - { - var theoryData = new TheoryData(); - CallContext callContext = new CallContext(); - var utcNow = DateTime.UtcNow; - var expirationTime = utcNow + TimeSpan.FromHours(1); - - #region return CustomTokenReplayValidationError - // Test cases where delegate is overridden and return a CustomTokenReplayValidationError - // CustomTokenReplayValidationError : TokenReplayValidationError, ExceptionType: SecurityTokenReplayDetectedException - theoryData.Add(new TokenReplayExtensibilityTheoryData( - "CustomTokenReplayValidationDelegate", - utcNow, - CustomTokenReplayValidationDelegates.CustomTokenReplayValidationDelegate, - extraStackFrames: 1) - { - ExpectedException = new ExpectedException( - typeof(SecurityTokenReplayDetectedException), - nameof(CustomTokenReplayValidationDelegates.CustomTokenReplayValidationDelegate)), - TokenReplayValidationError = new CustomTokenReplayValidationError( - new MessageDetail( - nameof(CustomTokenReplayValidationDelegates.CustomTokenReplayValidationDelegate), null), - ValidationFailureType.TokenReplayValidationFailed, - typeof(SecurityTokenReplayDetectedException), - new StackFrame("CustomTokenReplayValidationDelegates.cs", 160), - expirationTime) - }); - - // CustomTokenReplayValidationError : TokenReplayValidationError, ExceptionType: CustomSecurityTokenReplayDetectedException : SecurityTokenReplayDetectedException - theoryData.Add(new TokenReplayExtensibilityTheoryData( - "CustomTokenReplayValidatorCustomExceptionDelegate", - utcNow, - CustomTokenReplayValidationDelegates.CustomTokenReplayValidatorCustomExceptionDelegate, - extraStackFrames: 1) - { - ExpectedException = new ExpectedException( - typeof(CustomSecurityTokenReplayDetectedException), - nameof(CustomTokenReplayValidationDelegates.CustomTokenReplayValidatorCustomExceptionDelegate)), - TokenReplayValidationError = new CustomTokenReplayValidationError( - new MessageDetail( - nameof(CustomTokenReplayValidationDelegates.CustomTokenReplayValidatorCustomExceptionDelegate), null), - ValidationFailureType.TokenReplayValidationFailed, - typeof(CustomSecurityTokenReplayDetectedException), - new StackFrame("CustomTokenReplayValidationDelegates.cs", 175), - expirationTime), - }); - - // CustomTokenReplayValidationError : TokenReplayValidationError, ExceptionType: NotSupportedException : SystemException - theoryData.Add(new TokenReplayExtensibilityTheoryData( - "CustomTokenReplayValidatorUnknownExceptionDelegate", - utcNow, - CustomTokenReplayValidationDelegates.CustomTokenReplayValidatorUnknownExceptionDelegate, - extraStackFrames: 1) - { - // CustomTokenReplayValidationError does not handle the exception type 'NotSupportedException' - ExpectedException = ExpectedException.SecurityTokenException( - LogHelper.FormatInvariant( - Tokens.LogMessages.IDX10002, // "IDX10002: Unknown exception type returned. Type: '{0}'. Message: '{1}'."; - typeof(NotSupportedException), - nameof(CustomTokenReplayValidationDelegates.CustomTokenReplayValidatorUnknownExceptionDelegate))), - TokenReplayValidationError = new CustomTokenReplayValidationError( - new MessageDetail( - nameof(CustomTokenReplayValidationDelegates.CustomTokenReplayValidatorUnknownExceptionDelegate), null), - ValidationFailureType.TokenReplayValidationFailed, - typeof(NotSupportedException), - new StackFrame("CustomTokenReplayValidationDelegates.cs", 205), - expirationTime), - }); - - // CustomTokenReplayValidationError : TokenReplayValidationError, ExceptionType: NotSupportedException : SystemException, ValidationFailureType: CustomAudienceValidationFailureType - theoryData.Add(new TokenReplayExtensibilityTheoryData( - "CustomTokenReplayValidatorCustomExceptionCustomFailureTypeDelegate", - utcNow, - CustomTokenReplayValidationDelegates.CustomTokenReplayValidatorCustomExceptionCustomFailureTypeDelegate, - extraStackFrames: 1) - { - ExpectedException = new ExpectedException( - typeof(CustomSecurityTokenReplayDetectedException), - nameof(CustomTokenReplayValidationDelegates.CustomTokenReplayValidatorCustomExceptionCustomFailureTypeDelegate)), - TokenReplayValidationError = new CustomTokenReplayValidationError( - new MessageDetail( - nameof(CustomTokenReplayValidationDelegates.CustomTokenReplayValidatorCustomExceptionCustomFailureTypeDelegate), null), - CustomTokenReplayValidationError.CustomTokenReplayValidationFailureType, - typeof(CustomSecurityTokenReplayDetectedException), - new StackFrame("CustomTokenReplayValidationDelegates.cs", 190), - expirationTime), - }); - #endregion - - #region return TokenReplayValidationError - // Test cases where delegate is overridden and return an TokenReplayValidationError - // TokenReplayValidationError : ValidationError, ExceptionType: SecurityTokenReplayDetectedException - theoryData.Add(new TokenReplayExtensibilityTheoryData( - "TokenReplayValidationDelegate", - utcNow, - CustomTokenReplayValidationDelegates.TokenReplayValidationDelegate, - extraStackFrames: 1) - { - ExpectedException = new ExpectedException( - typeof(SecurityTokenReplayDetectedException), - nameof(CustomTokenReplayValidationDelegates.TokenReplayValidationDelegate)), - TokenReplayValidationError = new TokenReplayValidationError( - new MessageDetail( - nameof(CustomTokenReplayValidationDelegates.TokenReplayValidationDelegate), null), - ValidationFailureType.TokenReplayValidationFailed, - typeof(SecurityTokenReplayDetectedException), - new StackFrame("CustomTokenReplayValidationDelegates.cs", 235), - expirationTime) - }); - - // TokenReplayValidationError : ValidationError, ExceptionType: CustomSecurityTokenReplayDetectedException : SecurityTokenReplayDetectedException - theoryData.Add(new TokenReplayExtensibilityTheoryData( - "TokenReplayValidatorCustomTokenReplayDetectedExceptionTypeDelegate", - utcNow, - CustomTokenReplayValidationDelegates.TokenReplayValidatorCustomTokenReplayDetectedExceptionTypeDelegate, - extraStackFrames: 1) - { - // TokenReplayValidationError does not handle the exception type 'CustomSecurityTokenReplayDetectedException' - ExpectedException = ExpectedException.SecurityTokenException( - LogHelper.FormatInvariant( - Tokens.LogMessages.IDX10002, // "IDX10002: Unknown exception type returned. Type: '{0}'. Message: '{1}'."; - typeof(CustomSecurityTokenReplayDetectedException), - nameof(CustomTokenReplayValidationDelegates.TokenReplayValidatorCustomTokenReplayDetectedExceptionTypeDelegate))), - TokenReplayValidationError = new TokenReplayValidationError( - new MessageDetail( - nameof(CustomTokenReplayValidationDelegates.TokenReplayValidatorCustomTokenReplayDetectedExceptionTypeDelegate), null), - ValidationFailureType.TokenReplayValidationFailed, - typeof(CustomSecurityTokenReplayDetectedException), - new StackFrame("CustomTokenReplayValidationDelegates.cs", 259), - expirationTime) - }); - - // TokenReplayValidationError : ValidationError, ExceptionType: CustomSecurityTokenException : SystemException - theoryData.Add(new TokenReplayExtensibilityTheoryData( - "TokenReplayValidatorCustomExceptionTypeDelegate", - utcNow, - CustomTokenReplayValidationDelegates.TokenReplayValidatorCustomExceptionTypeDelegate, - extraStackFrames: 1) - { - // TokenReplayValidationError does not handle the exception type 'CustomSecurityTokenException' - ExpectedException = ExpectedException.SecurityTokenException( - LogHelper.FormatInvariant( - Tokens.LogMessages.IDX10002, // "IDX10002: Unknown exception type returned. Type: '{0}'. Message: '{1}'."; - typeof(CustomSecurityTokenException), - nameof(CustomTokenReplayValidationDelegates.TokenReplayValidatorCustomExceptionTypeDelegate))), - TokenReplayValidationError = new TokenReplayValidationError( - new MessageDetail( - nameof(CustomTokenReplayValidationDelegates.TokenReplayValidatorCustomExceptionTypeDelegate), null), - ValidationFailureType.TokenReplayValidationFailed, - typeof(CustomSecurityTokenException), - new StackFrame("CustomTokenReplayValidationDelegates.cs", 274), - expirationTime) - }); - - // TokenReplayValidationError : ValidationError, ExceptionType: SecurityTokenReplayDetectedException, inner: CustomSecurityTokenReplayDetectedException - theoryData.Add(new TokenReplayExtensibilityTheoryData( - "TokenReplayValidatorThrows", - utcNow, - CustomTokenReplayValidationDelegates.TokenReplayValidatorThrows, - extraStackFrames: 0) - { - ExpectedException = new ExpectedException( - typeof(SecurityTokenReplayDetectedException), - string.Format(Tokens.LogMessages.IDX10276), - typeof(CustomSecurityTokenReplayDetectedException)), - TokenReplayValidationError = new TokenReplayValidationError( - new MessageDetail( - string.Format(Tokens.LogMessages.IDX10276), null), - ValidationFailureType.TokenReplayValidatorThrew, - typeof(SecurityTokenReplayDetectedException), - new StackFrame("Saml2SecurityTokenHandler.ValidateToken.Internal.cs", 250), - expirationTime, - new SecurityTokenReplayDetectedException(nameof(CustomTokenReplayValidationDelegates.TokenReplayValidatorThrows)) - ) - }); - #endregion - - return theoryData; - } + await ExtensibilityTesting.ValidateTokenAsync_Extensibility( + theoryData, + this, + nameof(ValidateTokenAsync_TokenReplayValidator_Extensibility)); } - public class TokenReplayExtensibilityTheoryData : TheoryDataBase + public static TheoryData GenerateTokenReplayExtensibilityTestCases( + string tokenHandlerType, + int extraStackFrames) { - internal TokenReplayExtensibilityTheoryData(string testId, DateTime utcNow, TokenReplayValidationDelegate tokenReplayValidator, int extraStackFrames) : base(testId) - { - Saml2Token = (Saml2SecurityToken)Saml2SecurityTokenHandler.CreateToken( - new SecurityTokenDescriptor() - { - Subject = Default.SamlClaimsIdentity, - Issuer = Default.Issuer, - IssuedAt = utcNow, - NotBefore = utcNow, - Expires = utcNow + TimeSpan.FromHours(1), - }); - - ValidationParameters = new ValidationParameters - { - AlgorithmValidator = SkipValidationDelegates.SkipAlgorithmValidation, - AudienceValidator = SkipValidationDelegates.SkipAudienceValidation, - IssuerValidatorAsync = SkipValidationDelegates.SkipIssuerValidation, - IssuerSigningKeyValidator = SkipValidationDelegates.SkipIssuerSigningKeyValidation, - LifetimeValidator = SkipValidationDelegates.SkipLifetimeValidation, - SignatureValidator = SkipValidationDelegates.SkipSignatureValidation, - TokenReplayValidator = tokenReplayValidator, - TokenTypeValidator = SkipValidationDelegates.SkipTokenTypeValidation - }; - - ExtraStackFrames = extraStackFrames; - } - - public Saml2SecurityToken Saml2Token { get; } - - public Saml2SecurityTokenHandler Saml2SecurityTokenHandler { get; } = new Saml2SecurityTokenHandler(); - - public bool IsValid { get; set; } - - internal ValidationParameters? ValidationParameters { get; set; } - - internal TokenReplayValidationError? TokenReplayValidationError { get; set; } - - internal int ExtraStackFrames { get; } + return ExtensibilityTesting.GenerateTokenReplayExtensibilityTestCases( + tokenHandlerType, + extraStackFrames, + "Saml2SecurityTokenHandler.ValidateToken.Internal.cs"); } } } diff --git a/test/Microsoft.IdentityModel.Tokens.Saml.Tests/SamlSecurityTokenHandler.Extensibility.Algorithm.cs b/test/Microsoft.IdentityModel.Tokens.Saml.Tests/SamlSecurityTokenHandler.Extensibility.Algorithm.cs index ade781d8ac..bdf117bece 100644 --- a/test/Microsoft.IdentityModel.Tokens.Saml.Tests/SamlSecurityTokenHandler.Extensibility.Algorithm.cs +++ b/test/Microsoft.IdentityModel.Tokens.Saml.Tests/SamlSecurityTokenHandler.Extensibility.Algorithm.cs @@ -1,13 +1,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -using System; -using System.Diagnostics; -using System.Threading; using System.Threading.Tasks; -using Microsoft.IdentityModel.Logging; -using Microsoft.IdentityModel.TestUtils; - +using Microsoft.IdentityModel.TestUtils.TokenValidationExtensibility.Tests; using Xunit; #nullable enable @@ -15,322 +10,27 @@ namespace Microsoft.IdentityModel.Tokens.Saml.Extensibility.Tests { public partial class SamlSecurityTokenHandlerValidateTokenAsyncTests { - [Theory, MemberData(nameof(Algorithm_ExtensibilityTestCases), DisableDiscoveryEnumeration = true)] - public async Task ValidateTokenAsync_AlgorithmValidator_Extensibility(AlgorithmExtensibilityTheoryData theoryData) + [Theory, MemberData( + nameof(GenerateAlgorithmExtensibilityTestCases), + parameters: ["SAML", 1], + DisableDiscoveryEnumeration = true)] + public async Task ValidateTokenAsync_AlgorithmValidator_Extensibility( + AlgorithmExtensibilityTheoryData theoryData) { - var context = TestUtilities.WriteHeader($"{this}.{nameof(ValidateTokenAsync_AlgorithmValidator_Extensibility)}", theoryData); - context.IgnoreType = false; - for (int i = 0; i < theoryData.ExtraStackFrames; i++) - theoryData.ValidationError!.AddStackFrame(new StackFrame(false)); - - SamlSecurityToken SamlToken = (SamlSecurityToken)theoryData.SamlSecurityTokenHandler.CreateToken(new SecurityTokenDescriptor() - { - Issuer = Default.Issuer, - Subject = Default.SamlClaimsIdentity, - SigningCredentials = KeyingMaterial.DefaultX509SigningCreds_2048_RsaSha2_Sha2, - }); - theoryData.SamlToken = theoryData.SamlSecurityTokenHandler.ReadSamlToken(SamlToken.Assertion.CanonicalString); - - theoryData.ValidationParameters!.IssuerSigningKeys.Add(theoryData.SigningKey); - - try - { - ValidationResult validationResult = await theoryData.SamlSecurityTokenHandler.ValidateTokenAsync( - theoryData.SamlToken!, - theoryData.ValidationParameters!, - theoryData.CallContext, - CancellationToken.None); - - if (validationResult.IsValid) - { - // We expect the validation to fail, but it passed - context.AddDiff("ValidationResult is Valid."); - } - else - { - ValidationError validationError = validationResult.UnwrapError(); - - if (validationError is SignatureValidationError signatureValidationError && - signatureValidationError.InnerValidationError is not null) - { - IdentityComparer.AreValidationErrorsEqual( - signatureValidationError.InnerValidationError, - theoryData.ValidationError, - context); - } - else - { - IdentityComparer.AreValidationErrorsEqual( - validationError, - theoryData.ValidationError, - context); - } - - var exception = validationError.GetException(); - theoryData.ExpectedException.ProcessException(exception, context); - // Process the inner exception since invalid algorithm exceptions are wrapped inside - // invalid signature exceptions - if (theoryData.ExpectedInnerException is not null) - theoryData.ExpectedInnerException.ProcessException(exception.InnerException, context); - } - } - catch (Exception ex) - { - // We expect the validation to fail, but it threw an exception - context.AddDiff($"ValidateTokenAsync threw exception: {ex}"); - } - - TestUtilities.AssertFailIfErrors(context); + await ExtensibilityTesting.ValidateTokenAsync_Extensibility( + theoryData, + this, + nameof(ValidateTokenAsync_AlgorithmValidator_Extensibility)); } - public static TheoryData Algorithm_ExtensibilityTestCases + public static TheoryData GenerateAlgorithmExtensibilityTestCases( + string tokenHandlerType, + int extraStackFrames) { - get - { - var theoryData = new TheoryData(); - CallContext callContext = new CallContext(); - var utcNow = DateTime.UtcNow; - var utcPlusOneHour = utcNow + TimeSpan.FromHours(1); - - #region return CustomAlgorithmValidationError - // Test cases where delegate is overridden and return a CustomAlgorithmValidationError - // CustomAlgorithmValidationError : AlgorithmValidationError, ExceptionType: SecurityTokenInvalidAlgorithmException - theoryData.Add(new AlgorithmExtensibilityTheoryData( - "CustomAlgorithmValidatorDelegate", - utcNow, - CustomAlgorithmValidationDelegates.CustomAlgorithmValidatorDelegate, - extraStackFrames: 1) - { - ExpectedException = new ExpectedException( - typeof(SecurityTokenInvalidSignatureException), - "IDX10518:", - typeof(SecurityTokenInvalidAlgorithmException)), - ExpectedInnerException = new ExpectedException( - typeof(SecurityTokenInvalidAlgorithmException), - nameof(CustomAlgorithmValidationDelegates.CustomAlgorithmValidatorDelegate)), - ValidationError = new CustomAlgorithmValidationError( - new MessageDetail( - nameof(CustomAlgorithmValidationDelegates.CustomAlgorithmValidatorDelegate), null), - ValidationFailureType.AlgorithmValidationFailed, - typeof(SecurityTokenInvalidAlgorithmException), - new StackFrame("CustomAlgorithmValidationDelegates.cs", 160), - "algorithm") - }); - - // CustomAlgorithmValidationError : AlgorithmValidationError, ExceptionType: CustomSecurityTokenInvalidAlgorithmException : SecurityTokenInvalidAlgorithmException - theoryData.Add(new AlgorithmExtensibilityTheoryData( - "CustomAlgorithmValidatorCustomExceptionDelegate", - utcNow, - CustomAlgorithmValidationDelegates.CustomAlgorithmValidatorCustomExceptionDelegate, - extraStackFrames: 1) - { - ExpectedException = new ExpectedException( - typeof(SecurityTokenInvalidSignatureException), - "IDX10518:", - typeof(CustomSecurityTokenInvalidAlgorithmException)), - ExpectedInnerException = new ExpectedException( - typeof(CustomSecurityTokenInvalidAlgorithmException), - nameof(CustomAlgorithmValidationDelegates.CustomAlgorithmValidatorCustomExceptionDelegate)), - ValidationError = new CustomAlgorithmValidationError( - new MessageDetail( - nameof(CustomAlgorithmValidationDelegates.CustomAlgorithmValidatorCustomExceptionDelegate), null), - ValidationFailureType.AlgorithmValidationFailed, - typeof(CustomSecurityTokenInvalidAlgorithmException), - new StackFrame("CustomAlgorithmValidationDelegates.cs", 175), - "algorithm"), - }); - - // CustomAlgorithmValidationError : AlgorithmValidationError, ExceptionType: NotSupportedException : SystemException - theoryData.Add(new AlgorithmExtensibilityTheoryData( - "CustomAlgorithmValidatorUnknownExceptionDelegate", - utcNow, - CustomAlgorithmValidationDelegates.CustomAlgorithmValidatorUnknownExceptionDelegate, - extraStackFrames: 1) - { - // CustomAlgorithmValidationError does not handle the exception type 'NotSupportedException' - ExpectedException = new ExpectedException( - typeof(SecurityTokenInvalidSignatureException), - "IDX10518:", - typeof(SecurityTokenException)), - ExpectedInnerException = ExpectedException.SecurityTokenException( - LogHelper.FormatInvariant( - Tokens.LogMessages.IDX10002, // "IDX10002: Unknown exception type returned. Type: '{0}'. Message: '{1}'."; - typeof(NotSupportedException), - nameof(CustomAlgorithmValidationDelegates.CustomAlgorithmValidatorUnknownExceptionDelegate))), - ValidationError = new CustomAlgorithmValidationError( - new MessageDetail( - nameof(CustomAlgorithmValidationDelegates.CustomAlgorithmValidatorUnknownExceptionDelegate), null), - ValidationFailureType.AlgorithmValidationFailed, - typeof(NotSupportedException), - new StackFrame("CustomAlgorithmValidationDelegates.cs", 205), - "algorithm"), - }); - - // CustomAlgorithmValidationError : AlgorithmValidationError, ExceptionType: NotSupportedException : SystemException, ValidationFailureType: CustomAudienceValidationFailureType - theoryData.Add(new AlgorithmExtensibilityTheoryData( - "CustomAlgorithmValidatorCustomExceptionCustomFailureTypeDelegate", - utcNow, - CustomAlgorithmValidationDelegates.CustomAlgorithmValidatorCustomExceptionCustomFailureTypeDelegate, - extraStackFrames: 1) - { - ExpectedException = new ExpectedException( - typeof(SecurityTokenInvalidSignatureException), - "IDX10518:", - typeof(CustomSecurityTokenInvalidAlgorithmException)), - ExpectedInnerException = new ExpectedException( - typeof(CustomSecurityTokenInvalidAlgorithmException), - nameof(CustomAlgorithmValidationDelegates.CustomAlgorithmValidatorCustomExceptionCustomFailureTypeDelegate)), - ValidationError = new CustomAlgorithmValidationError( - new MessageDetail( - nameof(CustomAlgorithmValidationDelegates.CustomAlgorithmValidatorCustomExceptionCustomFailureTypeDelegate), null), - CustomAlgorithmValidationError.CustomAlgorithmValidationFailureType, - typeof(CustomSecurityTokenInvalidAlgorithmException), - new StackFrame("CustomAlgorithmValidationDelegates.cs", 190), - "algorithm"), - }); - #endregion - - #region return AlgorithmValidationError - // Test cases where delegate is overridden and return an AlgorithmValidationError - // AlgorithmValidationError : ValidationError, ExceptionType: SecurityTokenInvalidAlgorithmException - theoryData.Add(new AlgorithmExtensibilityTheoryData( - "AlgorithmValidatorDelegate", - utcNow, - CustomAlgorithmValidationDelegates.AlgorithmValidatorDelegate, - extraStackFrames: 1) - { - ExpectedException = new ExpectedException( - typeof(SecurityTokenInvalidSignatureException), - "IDX10518:", - typeof(SecurityTokenInvalidAlgorithmException)), - ExpectedInnerException = new ExpectedException( - typeof(SecurityTokenInvalidAlgorithmException), - nameof(CustomAlgorithmValidationDelegates.AlgorithmValidatorDelegate)), - ValidationError = new AlgorithmValidationError( - new MessageDetail( - nameof(CustomAlgorithmValidationDelegates.AlgorithmValidatorDelegate), null), - ValidationFailureType.AlgorithmValidationFailed, - typeof(SecurityTokenInvalidAlgorithmException), - new StackFrame("CustomAlgorithmValidationDelegates.cs", 235), - "algorithm") - }); - - // AlgorithmValidationError : ValidationError, ExceptionType: CustomSecurityTokenInvalidAlgorithmException : SecurityTokenInvalidAlgorithmException - theoryData.Add(new AlgorithmExtensibilityTheoryData( - "AlgorithmValidatorCustomAlgorithmExceptionTypeDelegate", - utcNow, - CustomAlgorithmValidationDelegates.AlgorithmValidatorCustomAlgorithmExceptionTypeDelegate, - extraStackFrames: 1) - { - // AlgorithmValidationError does not handle the exception type 'CustomSecurityTokenInvalidAlgorithmException' - ExpectedException = new ExpectedException( - typeof(SecurityTokenInvalidSignatureException), - "IDX10518:", - typeof(SecurityTokenException)), - ExpectedInnerException = ExpectedException.SecurityTokenException( - LogHelper.FormatInvariant( - Tokens.LogMessages.IDX10002, // "IDX10002: Unknown exception type returned. Type: '{0}'. Message: '{1}'."; - typeof(CustomSecurityTokenInvalidAlgorithmException), - nameof(CustomAlgorithmValidationDelegates.AlgorithmValidatorCustomAlgorithmExceptionTypeDelegate))), - ValidationError = new AlgorithmValidationError( - new MessageDetail( - nameof(CustomAlgorithmValidationDelegates.AlgorithmValidatorCustomAlgorithmExceptionTypeDelegate), null), - ValidationFailureType.AlgorithmValidationFailed, - typeof(CustomSecurityTokenInvalidAlgorithmException), - new StackFrame("CustomAlgorithmValidationDelegates.cs", 259), - "algorithm") - }); - - // AlgorithmValidationError : ValidationError, ExceptionType: CustomSecurityTokenException : SystemException - theoryData.Add(new AlgorithmExtensibilityTheoryData( - "AlgorithmValidatorCustomExceptionTypeDelegate", - utcNow, - CustomAlgorithmValidationDelegates.AlgorithmValidatorCustomExceptionTypeDelegate, - extraStackFrames: 1) - { - // AlgorithmValidationError does not handle the exception type 'CustomSecurityTokenException' - ExpectedException = new ExpectedException( - typeof(SecurityTokenInvalidSignatureException), - "IDX10518:", - typeof(SecurityTokenException)), - ExpectedInnerException = ExpectedException.SecurityTokenException( - LogHelper.FormatInvariant( - Tokens.LogMessages.IDX10002, // "IDX10002: Unknown exception type returned. Type: '{0}'. Message: '{1}'."; - typeof(CustomSecurityTokenException), - nameof(CustomAlgorithmValidationDelegates.AlgorithmValidatorCustomExceptionTypeDelegate))), - ValidationError = new AlgorithmValidationError( - new MessageDetail( - nameof(CustomAlgorithmValidationDelegates.AlgorithmValidatorCustomExceptionTypeDelegate), null), - ValidationFailureType.AlgorithmValidationFailed, - typeof(CustomSecurityTokenException), - new StackFrame("CustomAlgorithmValidationDelegates.cs", 274), - "algorithm") - }); - - // SignatureValidationError : ValidationError, ExceptionType: SecurityTokenInvalidSignatureException, inner: CustomSecurityTokenInvalidAlgorithmException - theoryData.Add(new AlgorithmExtensibilityTheoryData( - "AlgorithmValidatorThrows", - utcNow, - CustomAlgorithmValidationDelegates.AlgorithmValidatorThrows, - extraStackFrames: 2) - { - ExpectedException = new ExpectedException( - typeof(SecurityTokenInvalidSignatureException), - "IDX10273:", - typeof(CustomSecurityTokenInvalidAlgorithmException)), - ExpectedInnerException = new ExpectedException( - typeof(CustomSecurityTokenInvalidAlgorithmException), - nameof(CustomAlgorithmValidationDelegates.AlgorithmValidatorThrows)), - ValidationError = new SignatureValidationError( - new MessageDetail( - string.Format(Tokens.LogMessages.IDX10273), null), - ValidationFailureType.AlgorithmValidatorThrew, - typeof(SecurityTokenInvalidSignatureException), - new StackFrame("SamlSecurityTokenHandler.ValidateSignature.cs", 250), - null, // no inner validation error - new CustomSecurityTokenInvalidAlgorithmException(nameof(CustomAlgorithmValidationDelegates.AlgorithmValidatorThrows), null) - ) - }); - #endregion - - return theoryData; - } - } - - public class AlgorithmExtensibilityTheoryData : TheoryDataBase - { - internal AlgorithmExtensibilityTheoryData(string testId, DateTime utcNow, AlgorithmValidationDelegate algorithmValidator, int extraStackFrames) : base(testId) - { - ValidationParameters = new ValidationParameters - { - // We leave the default signature validator to call the custom algorithm validator - AlgorithmValidator = algorithmValidator, - AudienceValidator = SkipValidationDelegates.SkipAudienceValidation, - IssuerValidatorAsync = SkipValidationDelegates.SkipIssuerValidation, - IssuerSigningKeyValidator = SkipValidationDelegates.SkipIssuerSigningKeyValidation, - LifetimeValidator = SkipValidationDelegates.SkipLifetimeValidation, - TokenReplayValidator = SkipValidationDelegates.SkipTokenReplayValidation, - TokenTypeValidator = SkipValidationDelegates.SkipTokenTypeValidation, - }; - - ExtraStackFrames = extraStackFrames; - } - - public SamlSecurityToken? SamlToken { get; set; } - - public SamlSecurityTokenHandler SamlSecurityTokenHandler { get; } = new SamlSecurityTokenHandler(); - - public bool IsValid { get; set; } - - internal ValidationError? ValidationError { get; set; } - - public ExpectedException? ExpectedInnerException { get; set; } - - internal int ExtraStackFrames { get; } - - internal ValidationParameters ValidationParameters { get; } - - public SecurityKey SigningKey { get; set; } = KeyingMaterial.DefaultX509SigningCreds_2048_RsaSha2_Sha2.Key; + return ExtensibilityTesting.GenerateAlgorithmExtensibilityTestCases( + tokenHandlerType, + extraStackFrames, + "SamlSecurityTokenHandler.ValidateSignature.cs"); } } } diff --git a/test/Microsoft.IdentityModel.Tokens.Saml.Tests/SamlSecurityTokenHandler.Extensibility.IssuerSigningKey.cs b/test/Microsoft.IdentityModel.Tokens.Saml.Tests/SamlSecurityTokenHandler.Extensibility.IssuerSigningKey.cs index a6d68dda0e..2c0bf99497 100644 --- a/test/Microsoft.IdentityModel.Tokens.Saml.Tests/SamlSecurityTokenHandler.Extensibility.IssuerSigningKey.cs +++ b/test/Microsoft.IdentityModel.Tokens.Saml.Tests/SamlSecurityTokenHandler.Extensibility.IssuerSigningKey.cs @@ -1,13 +1,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -using System; -using System.Diagnostics; -using System.Threading; using System.Threading.Tasks; -using Microsoft.IdentityModel.Logging; -using Microsoft.IdentityModel.TestUtils; - +using Microsoft.IdentityModel.TestUtils.TokenValidationExtensibility.Tests; using Xunit; #nullable enable @@ -15,268 +10,27 @@ namespace Microsoft.IdentityModel.Tokens.Saml.Extensibility.Tests { public partial class SamlSecurityTokenHandlerValidateTokenAsyncTests { - [Theory, MemberData(nameof(IssuerSigningKey_ExtensibilityTestCases), DisableDiscoveryEnumeration = true)] - public async Task ValidateTokenAsync_IssuerSigningKeyValidator_Extensibility(IssuerSigningKeyExtensibilityTheoryData theoryData) - { - var context = TestUtilities.WriteHeader($"{this}.{nameof(ValidateTokenAsync_IssuerSigningKeyValidator_Extensibility)}", theoryData); - context.IgnoreType = false; - for (int i = 0; i < theoryData.ExtraStackFrames; i++) - theoryData.IssuerSigningKeyValidationError!.AddStackFrame(new StackFrame(false)); - - try - { - ValidationResult validationResult = await theoryData.SamlSecurityTokenHandler.ValidateTokenAsync( - theoryData.SamlToken!, - theoryData.ValidationParameters!, - theoryData.CallContext, - CancellationToken.None); - - if (validationResult.IsValid) - { - context.AddDiff("validationResult.IsValid is true, expected false"); - } - else - { - ValidationError validationError = validationResult.UnwrapError(); - IdentityComparer.AreValidationErrorsEqual(validationError, theoryData.IssuerSigningKeyValidationError, context); - theoryData.ExpectedException.ProcessException(validationError.GetException(), context); - } - } - catch (Exception ex) - { - theoryData.ExpectedException.ProcessException(ex, context); - } - - TestUtilities.AssertFailIfErrors(context); - } - - public static TheoryData IssuerSigningKey_ExtensibilityTestCases + [Theory, MemberData( + nameof(GenerateIssuerSigningKeyExtensibilityTestCases), + parameters: ["SAML", 1], + DisableDiscoveryEnumeration = true)] + public async Task ValidateTokenAsync_IssuerSigningKeyValidator_Extensibility( + IssuerSigningKeyExtensibilityTheoryData theoryData) { - get - { - var theoryData = new TheoryData(); - CallContext callContext = new CallContext(); - var utcNow = DateTime.UtcNow; - var utcPlusOneHour = utcNow + TimeSpan.FromHours(1); - - #region return CustomIssuerSigningKeyValidationError - // Test cases where delegate is overridden and return a CustomIssuerSigningKeyValidationError - // CustomIssuerSigningKeyValidationError : IssuerSigningKeyValidationError, ExceptionType: SecurityTokenInvalidIssuerSigningKeyException - theoryData.Add(new IssuerSigningKeyExtensibilityTheoryData( - "CustomIssuerSigningKeyValidatorDelegate", - utcNow, - CustomIssuerSigningKeyValidationDelegates.CustomIssuerSigningKeyValidatorDelegate, - extraStackFrames: 1) - { - ExpectedException = new ExpectedException( - typeof(SecurityTokenInvalidSigningKeyException), - nameof(CustomIssuerSigningKeyValidationDelegates.CustomIssuerSigningKeyValidatorDelegate)), - IssuerSigningKeyValidationError = new CustomIssuerSigningKeyValidationError( - new MessageDetail( - nameof(CustomIssuerSigningKeyValidationDelegates.CustomIssuerSigningKeyValidatorDelegate), null), - ValidationFailureType.SigningKeyValidationFailed, - typeof(SecurityTokenInvalidSigningKeyException), - new StackFrame("CustomIssuerSigningKeyValidationDelegates.cs", 160), - null) - }); - - // CustomIssuerSigningKeyValidationError : IssuerSigningKeyValidationError, ExceptionType: CustomSecurityTokenInvalidIssuerSigningKeyException : SecurityTokenInvalidIssuerSigningKeyException - theoryData.Add(new IssuerSigningKeyExtensibilityTheoryData( - "CustomIssuerSigningKeyValidatorCustomExceptionDelegate", - utcNow, - CustomIssuerSigningKeyValidationDelegates.CustomIssuerSigningKeyValidatorCustomExceptionDelegate, - extraStackFrames: 1) - { - ExpectedException = new ExpectedException( - typeof(CustomSecurityTokenInvalidSigningKeyException), - nameof(CustomIssuerSigningKeyValidationDelegates.CustomIssuerSigningKeyValidatorCustomExceptionDelegate)), - IssuerSigningKeyValidationError = new CustomIssuerSigningKeyValidationError( - new MessageDetail( - nameof(CustomIssuerSigningKeyValidationDelegates.CustomIssuerSigningKeyValidatorCustomExceptionDelegate), null), - ValidationFailureType.SigningKeyValidationFailed, - typeof(CustomSecurityTokenInvalidSigningKeyException), - new StackFrame("CustomIssuerSigningKeyValidationDelegates.cs", 175), - null) - }); - - // CustomIssuerSigningKeyValidationError : IssuerSigningKeyValidationError, ExceptionType: NotSupportedException : SystemException - theoryData.Add(new IssuerSigningKeyExtensibilityTheoryData( - "CustomIssuerSigningKeyValidatorUnknownExceptionDelegate", - utcNow, - CustomIssuerSigningKeyValidationDelegates.CustomIssuerSigningKeyValidatorUnknownExceptionDelegate, - extraStackFrames: 1) - { - // CustomIssuerSigningKeyValidationError does not handle the exception type 'NotSupportedException' - ExpectedException = ExpectedException.SecurityTokenException( - LogHelper.FormatInvariant( - Tokens.LogMessages.IDX10002, // "IDX10002: Unknown exception type returned. Type: '{0}'. Message: '{1}'."; - typeof(NotSupportedException), - nameof(CustomIssuerSigningKeyValidationDelegates.CustomIssuerSigningKeyValidatorUnknownExceptionDelegate))), - IssuerSigningKeyValidationError = new CustomIssuerSigningKeyValidationError( - new MessageDetail( - nameof(CustomIssuerSigningKeyValidationDelegates.CustomIssuerSigningKeyValidatorUnknownExceptionDelegate), null), - ValidationFailureType.SigningKeyValidationFailed, - typeof(NotSupportedException), - new StackFrame("CustomIssuerSigningKeyValidationDelegates.cs", 205), - null) - }); - - // CustomIssuerSigningKeyValidationError : IssuerSigningKeyValidationError, ExceptionType: NotSupportedException : SystemException, ValidationFailureType: CustomAudienceValidationFailureType - theoryData.Add(new IssuerSigningKeyExtensibilityTheoryData( - "CustomIssuerSigningKeyValidatorCustomExceptionCustomFailureTypeDelegate", - utcNow, - CustomIssuerSigningKeyValidationDelegates.CustomIssuerSigningKeyValidatorCustomExceptionCustomFailureTypeDelegate, - extraStackFrames: 1) - { - ExpectedException = new ExpectedException( - typeof(CustomSecurityTokenInvalidSigningKeyException), - nameof(CustomIssuerSigningKeyValidationDelegates.CustomIssuerSigningKeyValidatorCustomExceptionCustomFailureTypeDelegate)), - IssuerSigningKeyValidationError = new CustomIssuerSigningKeyValidationError( - new MessageDetail( - nameof(CustomIssuerSigningKeyValidationDelegates.CustomIssuerSigningKeyValidatorCustomExceptionCustomFailureTypeDelegate), null), - CustomIssuerSigningKeyValidationError.CustomIssuerSigningKeyValidationFailureType, - typeof(CustomSecurityTokenInvalidSigningKeyException), - new StackFrame("CustomIssuerSigningKeyValidationDelegates.cs", 190), - null), - }); - #endregion - - #region return IssuerSigningKeyValidationError - // Test cases where delegate is overridden and return an IssuerSigningKeyValidationError - // IssuerSigningKeyValidationError : ValidationError, ExceptionType: SecurityTokenInvalidIssuerSigningKeyException - theoryData.Add(new IssuerSigningKeyExtensibilityTheoryData( - "IssuerSigningKeyValidatorDelegate", - utcNow, - CustomIssuerSigningKeyValidationDelegates.IssuerSigningKeyValidatorDelegate, - extraStackFrames: 1) - { - ExpectedException = new ExpectedException( - typeof(SecurityTokenInvalidSigningKeyException), - nameof(CustomIssuerSigningKeyValidationDelegates.IssuerSigningKeyValidatorDelegate)), - IssuerSigningKeyValidationError = new IssuerSigningKeyValidationError( - new MessageDetail( - nameof(CustomIssuerSigningKeyValidationDelegates.IssuerSigningKeyValidatorDelegate), null), - ValidationFailureType.SigningKeyValidationFailed, - typeof(SecurityTokenInvalidSigningKeyException), - new StackFrame("CustomIssuerSigningKeyValidationDelegates.cs", 235), - null) - }); - - // IssuerSigningKeyValidationError : ValidationError, ExceptionType: CustomSecurityTokenInvalidIssuerSigningKeyException : SecurityTokenInvalidIssuerSigningKeyException - theoryData.Add(new IssuerSigningKeyExtensibilityTheoryData( - "IssuerSigningKeyValidatorCustomIssuerSigningKeyExceptionTypeDelegate", - utcNow, - CustomIssuerSigningKeyValidationDelegates.IssuerSigningKeyValidatorCustomIssuerSigningKeyExceptionTypeDelegate, - extraStackFrames: 1) - { - // IssuerSigningKeyValidationError does not handle the exception type 'CustomSecurityTokenInvalidIssuerSigningKeyException' - ExpectedException = ExpectedException.SecurityTokenException( - LogHelper.FormatInvariant( - Tokens.LogMessages.IDX10002, // "IDX10002: Unknown exception type returned. Type: '{0}'. Message: '{1}'."; - typeof(CustomSecurityTokenInvalidSigningKeyException), - nameof(CustomIssuerSigningKeyValidationDelegates.IssuerSigningKeyValidatorCustomIssuerSigningKeyExceptionTypeDelegate))), - IssuerSigningKeyValidationError = new IssuerSigningKeyValidationError( - new MessageDetail( - nameof(CustomIssuerSigningKeyValidationDelegates.IssuerSigningKeyValidatorCustomIssuerSigningKeyExceptionTypeDelegate), null), - ValidationFailureType.SigningKeyValidationFailed, - typeof(CustomSecurityTokenInvalidSigningKeyException), - new StackFrame("CustomIssuerSigningKeyValidationDelegates.cs", 259), - null) - }); - - // IssuerSigningKeyValidationError : ValidationError, ExceptionType: CustomSecurityTokenException : SystemException - theoryData.Add(new IssuerSigningKeyExtensibilityTheoryData( - "IssuerSigningKeyValidatorCustomExceptionTypeDelegate", - utcNow, - CustomIssuerSigningKeyValidationDelegates.IssuerSigningKeyValidatorCustomExceptionTypeDelegate, - extraStackFrames: 1) - { - // IssuerSigningKeyValidationError does not handle the exception type 'CustomSecurityTokenException' - ExpectedException = ExpectedException.SecurityTokenException( - LogHelper.FormatInvariant( - Tokens.LogMessages.IDX10002, // "IDX10002: Unknown exception type returned. Type: '{0}'. Message: '{1}'."; - typeof(CustomSecurityTokenException), - nameof(CustomIssuerSigningKeyValidationDelegates.IssuerSigningKeyValidatorCustomExceptionTypeDelegate))), - IssuerSigningKeyValidationError = new IssuerSigningKeyValidationError( - new MessageDetail( - nameof(CustomIssuerSigningKeyValidationDelegates.IssuerSigningKeyValidatorCustomExceptionTypeDelegate), null), - ValidationFailureType.SigningKeyValidationFailed, - typeof(CustomSecurityTokenException), - new StackFrame("CustomIssuerSigningKeyValidationDelegates.cs", 274), - null) - }); - - // IssuerSigningKeyValidationError : ValidationError, ExceptionType: SecurityTokenInvalidIssuerSigningKeyException, inner: CustomSecurityTokenInvalidIssuerSigningKeyException - theoryData.Add(new IssuerSigningKeyExtensibilityTheoryData( - "IssuerSigningKeyValidatorThrows", - utcNow, - CustomIssuerSigningKeyValidationDelegates.IssuerSigningKeyValidatorThrows, - extraStackFrames: 0) - { - ExpectedException = new ExpectedException( - typeof(SecurityTokenInvalidSigningKeyException), - string.Format(Tokens.LogMessages.IDX10274), - typeof(CustomSecurityTokenInvalidSigningKeyException)), - IssuerSigningKeyValidationError = new IssuerSigningKeyValidationError( - new MessageDetail( - string.Format(Tokens.LogMessages.IDX10274), null), - ValidationFailureType.IssuerSigningKeyValidatorThrew, - typeof(SecurityTokenInvalidSigningKeyException), - new StackFrame("SamlSecurityTokenHandler.ValidateToken.Internal.cs", 250), - null, - new SecurityTokenInvalidSigningKeyException(nameof(CustomIssuerSigningKeyValidationDelegates.IssuerSigningKeyValidatorThrows)) - ) - }); - #endregion - - return theoryData; - } + await ExtensibilityTesting.ValidateTokenAsync_Extensibility( + theoryData, + this, + nameof(ValidateTokenAsync_IssuerSigningKeyValidator_Extensibility)); } - public class IssuerSigningKeyExtensibilityTheoryData : TheoryDataBase + public static TheoryData GenerateIssuerSigningKeyExtensibilityTestCases( + string tokenHandlerType, + int extraStackFrames) { - internal IssuerSigningKeyExtensibilityTheoryData(string testId, DateTime utcNow, IssuerSigningKeyValidationDelegate issuerSigningKeyValidator, int extraStackFrames) : base(testId) - { - SamlToken = (SamlSecurityToken)SamlSecurityTokenHandler.CreateToken( - new SecurityTokenDescriptor() - { - Subject = Default.SamlClaimsIdentity, - Issuer = Default.Issuer, - }); - - ValidationParameters = new ValidationParameters - { - AlgorithmValidator = SkipValidationDelegates.SkipAlgorithmValidation, - AudienceValidator = SkipValidationDelegates.SkipAudienceValidation, - IssuerValidatorAsync = SkipValidationDelegates.SkipIssuerValidation, - IssuerSigningKeyValidator = issuerSigningKeyValidator, - LifetimeValidator = SkipValidationDelegates.SkipLifetimeValidation, - SignatureValidator = (SecurityToken token, ValidationParameters validationParameters, BaseConfiguration? configuration, CallContext callContext) => - { - token.SigningKey = SigningKey; - - return SigningKey; - }, - TokenReplayValidator = SkipValidationDelegates.SkipTokenReplayValidation, - TokenTypeValidator = SkipValidationDelegates.SkipTokenTypeValidation - }; - - ExtraStackFrames = extraStackFrames; - } - - public SamlSecurityToken SamlToken { get; } - - public SamlSecurityTokenHandler SamlSecurityTokenHandler { get; } = new SamlSecurityTokenHandler(); - - public bool IsValid { get; set; } - - public SecurityKey SigningKey { get; set; } = KeyingMaterial.DefaultX509SigningCreds_2048_RsaSha2_Sha2.Key; - - internal ValidationParameters? ValidationParameters { get; set; } - - internal IssuerSigningKeyValidationError? IssuerSigningKeyValidationError { get; set; } - - internal int ExtraStackFrames { get; } + return ExtensibilityTesting.GenerateIssuerSigningKeyExtensibilityTestCases( + tokenHandlerType, + extraStackFrames, + "SamlSecurityTokenHandler.ValidateToken.Internal.cs"); } } } diff --git a/test/Microsoft.IdentityModel.Tokens.Saml.Tests/SamlSecurityTokenHandler.Extensibility.Signature.cs b/test/Microsoft.IdentityModel.Tokens.Saml.Tests/SamlSecurityTokenHandler.Extensibility.Signature.cs index 467bce3c42..85f57bb942 100644 --- a/test/Microsoft.IdentityModel.Tokens.Saml.Tests/SamlSecurityTokenHandler.Extensibility.Signature.cs +++ b/test/Microsoft.IdentityModel.Tokens.Saml.Tests/SamlSecurityTokenHandler.Extensibility.Signature.cs @@ -1,13 +1,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -using System; -using System.Diagnostics; -using System.Threading; using System.Threading.Tasks; -using Microsoft.IdentityModel.Logging; -using Microsoft.IdentityModel.TestUtils; - +using Microsoft.IdentityModel.TestUtils.TokenValidationExtensibility.Tests; using Xunit; #nullable enable @@ -15,255 +10,27 @@ namespace Microsoft.IdentityModel.Tokens.Saml.Extensibility.Tests { public partial class SamlSecurityTokenHandlerValidateTokenAsyncTests { - [Theory, MemberData(nameof(Signature_ExtensibilityTestCases), DisableDiscoveryEnumeration = true)] - public async Task ValidateTokenAsync_SignatureValidator_Extensibility(SignatureExtensibilityTheoryData theoryData) - { - var context = TestUtilities.WriteHeader($"{this}.{nameof(ValidateTokenAsync_SignatureValidator_Extensibility)}", theoryData); - context.IgnoreType = false; - for (int i = 0; i < theoryData.ExtraStackFrames; i++) - theoryData.SignatureValidationError!.AddStackFrame(new StackFrame(false)); - - try - { - ValidationResult validationResult = await theoryData.SamlSecurityTokenHandler.ValidateTokenAsync( - theoryData.SamlToken!, - theoryData.ValidationParameters!, - theoryData.CallContext, - CancellationToken.None); - - if (validationResult.IsValid) - { - // We expect the validation to fail, but it passed - context.AddDiff("ValidationResult is Valid."); - } - else - { - ValidationError validationError = validationResult.UnwrapError(); - IdentityComparer.AreValidationErrorsEqual(validationError, theoryData.SignatureValidationError, context); - theoryData.ExpectedException.ProcessException(validationError.GetException(), context); - } - } - catch (Exception ex) - { - theoryData.ExpectedException.ProcessException(ex, context); - } - - TestUtilities.AssertFailIfErrors(context); - } - - public static TheoryData Signature_ExtensibilityTestCases + [Theory, MemberData( + nameof(GenerateSignatureExtensibilityTestCases), + parameters: ["SAML", 2], + DisableDiscoveryEnumeration = true)] + public async Task ValidateTokenAsync_SignatureValidator_Extensibility( + SignatureExtensibilityTheoryData theoryData) { - get - { - var theoryData = new TheoryData(); - CallContext callContext = new CallContext(); - var utcNow = DateTime.UtcNow; - var utcPlusOneHour = utcNow + TimeSpan.FromHours(1); - - #region return CustomSignatureValidationError - // Test cases where delegate is overridden and return a CustomSignatureValidationError - // CustomSignatureValidationError : SignatureValidationError, ExceptionType: SecurityTokenInvalidSignatureException - theoryData.Add(new SignatureExtensibilityTheoryData( - "CustomSignatureValidatorDelegate", - utcNow, - CustomSignatureValidationDelegates.CustomSignatureValidatorDelegate, - extraStackFrames: 2) - { - ExpectedException = new ExpectedException( - typeof(SecurityTokenInvalidSignatureException), - nameof(CustomSignatureValidationDelegates.CustomSignatureValidatorDelegate)), - SignatureValidationError = new CustomSignatureValidationError( - new MessageDetail( - nameof(CustomSignatureValidationDelegates.CustomSignatureValidatorDelegate), null), - ValidationFailureType.SignatureValidationFailed, - typeof(SecurityTokenInvalidSignatureException), - new StackFrame("CustomSignatureValidationDelegates.cs", 160)) - }); - - // CustomSignatureValidationError : SignatureValidationError, ExceptionType: CustomSecurityTokenInvalidSignatureException : SecurityTokenInvalidSignatureException - theoryData.Add(new SignatureExtensibilityTheoryData( - "CustomSignatureValidatorCustomExceptionDelegate", - utcNow, - CustomSignatureValidationDelegates.CustomSignatureValidatorCustomExceptionDelegate, - extraStackFrames: 2) - { - ExpectedException = new ExpectedException( - typeof(CustomSecurityTokenInvalidSignatureException), - nameof(CustomSignatureValidationDelegates.CustomSignatureValidatorCustomExceptionDelegate)), - SignatureValidationError = new CustomSignatureValidationError( - new MessageDetail( - nameof(CustomSignatureValidationDelegates.CustomSignatureValidatorCustomExceptionDelegate), null), - ValidationFailureType.SignatureValidationFailed, - typeof(CustomSecurityTokenInvalidSignatureException), - new StackFrame("CustomSignatureValidationDelegates.cs", 175)), - }); - - // CustomSignatureValidationError : SignatureValidationError, ExceptionType: NotSupportedException : SystemException - theoryData.Add(new SignatureExtensibilityTheoryData( - "CustomSignatureValidatorUnknownExceptionDelegate", - utcNow, - CustomSignatureValidationDelegates.CustomSignatureValidatorUnknownExceptionDelegate, - extraStackFrames: 2) - { - // CustomSignatureValidationError does not handle the exception type 'NotSupportedException' - ExpectedException = ExpectedException.SecurityTokenException( - LogHelper.FormatInvariant( - Tokens.LogMessages.IDX10002, // "IDX10002: Unknown exception type returned. Type: '{0}'. Message: '{1}'."; - typeof(NotSupportedException), - nameof(CustomSignatureValidationDelegates.CustomSignatureValidatorUnknownExceptionDelegate))), - SignatureValidationError = new CustomSignatureValidationError( - new MessageDetail( - nameof(CustomSignatureValidationDelegates.CustomSignatureValidatorUnknownExceptionDelegate), null), - ValidationFailureType.SignatureValidationFailed, - typeof(NotSupportedException), - new StackFrame("CustomSignatureValidationDelegates.cs", 205)), - }); - - // CustomSignatureValidationError : SignatureValidationError, ExceptionType: NotSupportedException : SystemException, ValidationFailureType: CustomAudienceValidationFailureType - theoryData.Add(new SignatureExtensibilityTheoryData( - "CustomSignatureValidatorCustomExceptionCustomFailureTypeDelegate", - utcNow, - CustomSignatureValidationDelegates.CustomSignatureValidatorCustomExceptionCustomFailureTypeDelegate, - extraStackFrames: 2) - { - ExpectedException = new ExpectedException( - typeof(CustomSecurityTokenInvalidSignatureException), - nameof(CustomSignatureValidationDelegates.CustomSignatureValidatorCustomExceptionCustomFailureTypeDelegate)), - SignatureValidationError = new CustomSignatureValidationError( - new MessageDetail( - nameof(CustomSignatureValidationDelegates.CustomSignatureValidatorCustomExceptionCustomFailureTypeDelegate), null), - CustomSignatureValidationError.CustomSignatureValidationFailureType, - typeof(CustomSecurityTokenInvalidSignatureException), - new StackFrame("CustomSignatureValidationDelegates.cs", 190)), - }); - #endregion - - #region return SignatureValidationError - // Test cases where delegate is overridden and return an SignatureValidationError - // SignatureValidationError : ValidationError, ExceptionType: SecurityTokenInvalidSignatureException - theoryData.Add(new SignatureExtensibilityTheoryData( - "SignatureValidatorDelegate", - utcNow, - CustomSignatureValidationDelegates.SignatureValidatorDelegate, - extraStackFrames: 2) - { - ExpectedException = new ExpectedException( - typeof(SecurityTokenInvalidSignatureException), - nameof(CustomSignatureValidationDelegates.SignatureValidatorDelegate)), - SignatureValidationError = new SignatureValidationError( - new MessageDetail( - nameof(CustomSignatureValidationDelegates.SignatureValidatorDelegate), null), - ValidationFailureType.SignatureValidationFailed, - typeof(SecurityTokenInvalidSignatureException), - new StackFrame("CustomSignatureValidationDelegates.cs", 235)) - }); - - // SignatureValidationError : ValidationError, ExceptionType: CustomSecurityTokenInvalidSignatureException : SecurityTokenInvalidSignatureException - theoryData.Add(new SignatureExtensibilityTheoryData( - "SignatureValidatorCustomSignatureExceptionTypeDelegate", - utcNow, - CustomSignatureValidationDelegates.SignatureValidatorCustomSignatureExceptionTypeDelegate, - extraStackFrames: 2) - { - // SignatureValidationError does not handle the exception type 'CustomSecurityTokenInvalidSignatureException' - ExpectedException = ExpectedException.SecurityTokenException( - LogHelper.FormatInvariant( - Tokens.LogMessages.IDX10002, // "IDX10002: Unknown exception type returned. Type: '{0}'. Message: '{1}'."; - typeof(CustomSecurityTokenInvalidSignatureException), - nameof(CustomSignatureValidationDelegates.SignatureValidatorCustomSignatureExceptionTypeDelegate))), - SignatureValidationError = new SignatureValidationError( - new MessageDetail( - nameof(CustomSignatureValidationDelegates.SignatureValidatorCustomSignatureExceptionTypeDelegate), null), - ValidationFailureType.SignatureValidationFailed, - typeof(CustomSecurityTokenInvalidSignatureException), - new StackFrame("CustomSignatureValidationDelegates.cs", 259)) - }); - - // SignatureValidationError : ValidationError, ExceptionType: CustomSecurityTokenException : SystemException - theoryData.Add(new SignatureExtensibilityTheoryData( - "SignatureValidatorCustomExceptionTypeDelegate", - utcNow, - CustomSignatureValidationDelegates.SignatureValidatorCustomExceptionTypeDelegate, - extraStackFrames: 2) - { - // SignatureValidationError does not handle the exception type 'CustomSecurityTokenException' - ExpectedException = ExpectedException.SecurityTokenException( - LogHelper.FormatInvariant( - Tokens.LogMessages.IDX10002, // "IDX10002: Unknown exception type returned. Type: '{0}'. Message: '{1}'."; - typeof(CustomSecurityTokenException), - nameof(CustomSignatureValidationDelegates.SignatureValidatorCustomExceptionTypeDelegate))), - SignatureValidationError = new SignatureValidationError( - new MessageDetail( - nameof(CustomSignatureValidationDelegates.SignatureValidatorCustomExceptionTypeDelegate), null), - ValidationFailureType.SignatureValidationFailed, - typeof(CustomSecurityTokenException), - new StackFrame("CustomSignatureValidationDelegates.cs", 274)) - }); - - // SignatureValidationError : ValidationError, ExceptionType: SecurityTokenInvalidSignatureException, inner: CustomSecurityTokenInvalidSignatureException - theoryData.Add(new SignatureExtensibilityTheoryData( - "SignatureValidatorThrows", - utcNow, - CustomSignatureValidationDelegates.SignatureValidatorThrows, - extraStackFrames: 1) - { - ExpectedException = new ExpectedException( - typeof(SecurityTokenInvalidSignatureException), - string.Format(Tokens.LogMessages.IDX10272), - typeof(CustomSecurityTokenInvalidSignatureException)), - SignatureValidationError = new SignatureValidationError( - new MessageDetail( - string.Format(Tokens.LogMessages.IDX10272), null), - ValidationFailureType.SignatureValidatorThrew, - typeof(SecurityTokenInvalidSignatureException), - new StackFrame("SamlSecurityTokenHandler.ValidateSignature.cs", 250), - null, // no inner validation error - new SecurityTokenInvalidSignatureException(nameof(CustomSignatureValidationDelegates.SignatureValidatorThrows)) - ) - }); - #endregion - - return theoryData; - } + await ExtensibilityTesting.ValidateTokenAsync_Extensibility( + theoryData, + this, + nameof(ValidateTokenAsync_SignatureValidator_Extensibility)); } - public class SignatureExtensibilityTheoryData : TheoryDataBase + public static TheoryData GenerateSignatureExtensibilityTestCases( + string tokenHandlerType, + int extraStackFrames) { - internal SignatureExtensibilityTheoryData(string testId, DateTime utcNow, SignatureValidationDelegate signatureValidator, int extraStackFrames) : base(testId) - { - SamlToken = (SamlSecurityToken)SamlSecurityTokenHandler.CreateToken( - new SecurityTokenDescriptor() - { - Subject = Default.SamlClaimsIdentity, - Issuer = Default.Issuer, - }); - - ValidationParameters = new ValidationParameters - { - AlgorithmValidator = SkipValidationDelegates.SkipAlgorithmValidation, - AudienceValidator = SkipValidationDelegates.SkipAudienceValidation, - IssuerValidatorAsync = SkipValidationDelegates.SkipIssuerValidation, - IssuerSigningKeyValidator = SkipValidationDelegates.SkipIssuerSigningKeyValidation, - LifetimeValidator = SkipValidationDelegates.SkipLifetimeValidation, - SignatureValidator = signatureValidator, - TokenReplayValidator = SkipValidationDelegates.SkipTokenReplayValidation, - TokenTypeValidator = SkipValidationDelegates.SkipTokenTypeValidation - }; - - ExtraStackFrames = extraStackFrames; - } - - public SamlSecurityToken SamlToken { get; } - - public SamlSecurityTokenHandler SamlSecurityTokenHandler { get; } = new SamlSecurityTokenHandler(); - - public bool IsValid { get; set; } - - internal ValidationParameters ValidationParameters { get; } - - internal SignatureValidationError? SignatureValidationError { get; set; } - - internal int ExtraStackFrames { get; } + return ExtensibilityTesting.GenerateSignatureExtensibilityTestCases( + tokenHandlerType, + extraStackFrames, + "SamlSecurityTokenHandler.ValidateSignature.cs"); } } } diff --git a/test/Microsoft.IdentityModel.Tokens.Saml.Tests/SamlSecurityTokenHandler.Extensibility.TokenReplay.cs b/test/Microsoft.IdentityModel.Tokens.Saml.Tests/SamlSecurityTokenHandler.Extensibility.TokenReplay.cs index c603ebcacd..ca52b2eb49 100644 --- a/test/Microsoft.IdentityModel.Tokens.Saml.Tests/SamlSecurityTokenHandler.Extensibility.TokenReplay.cs +++ b/test/Microsoft.IdentityModel.Tokens.Saml.Tests/SamlSecurityTokenHandler.Extensibility.TokenReplay.cs @@ -1,13 +1,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -using System; -using System.Diagnostics; -using System.Threading; using System.Threading.Tasks; -using Microsoft.IdentityModel.Logging; -using Microsoft.IdentityModel.TestUtils; - +using Microsoft.IdentityModel.TestUtils.TokenValidationExtensibility.Tests; using Xunit; #nullable enable @@ -15,264 +10,27 @@ namespace Microsoft.IdentityModel.Tokens.Saml.Extensibility.Tests { public partial class SamlSecurityTokenHandlerValidateTokenAsyncTests { - [Theory, MemberData(nameof(TokenReplay_ExtensibilityTestCases), DisableDiscoveryEnumeration = true)] - public async Task ValidateTokenAsync_TokenReplayValidator_Extensibility(TokenReplayExtensibilityTheoryData theoryData) - { - var context = TestUtilities.WriteHeader($"{this}.{nameof(ValidateTokenAsync_TokenReplayValidator_Extensibility)}", theoryData); - context.IgnoreType = false; - for (int i = 0; i < theoryData.ExtraStackFrames; i++) - theoryData.TokenReplayValidationError!.AddStackFrame(new StackFrame(false)); - - try - { - ValidationResult validationResult = await theoryData.SamlSecurityTokenHandler.ValidateTokenAsync( - theoryData.SamlToken!, - theoryData.ValidationParameters!, - theoryData.CallContext, - CancellationToken.None); - - if (validationResult.IsValid) - { - context.Diffs.Add("validationResult.IsValid is true, expected false"); - } - else - { - ValidationError validationError = validationResult.UnwrapError(); - IdentityComparer.AreValidationErrorsEqual(validationError, theoryData.TokenReplayValidationError, context); - theoryData.ExpectedException.ProcessException(validationError.GetException(), context); - } - } - catch (Exception ex) - { - theoryData.ExpectedException.ProcessException(ex, context); - } - - TestUtilities.AssertFailIfErrors(context); - } - - public static TheoryData TokenReplay_ExtensibilityTestCases + [Theory, MemberData( + nameof(GenerateTokenReplayExtensibilityTestCases), + parameters: ["SAML", 1], + DisableDiscoveryEnumeration = true)] + public async Task ValidateTokenAsync_TokenReplayValidator_Extensibility( + TokenReplayExtensibilityTheoryData theoryData) { - get - { - var theoryData = new TheoryData(); - CallContext callContext = new CallContext(); - var utcNow = DateTime.UtcNow; - var expirationTime = utcNow + TimeSpan.FromHours(1); - - #region return CustomTokenReplayValidationError - // Test cases where delegate is overridden and return a CustomTokenReplayValidationError - // CustomTokenReplayValidationError : TokenReplayValidationError, ExceptionType: SecurityTokenReplayDetectedException - theoryData.Add(new TokenReplayExtensibilityTheoryData( - "CustomTokenReplayValidationDelegate", - utcNow, - CustomTokenReplayValidationDelegates.CustomTokenReplayValidationDelegate, - extraStackFrames: 1) - { - ExpectedException = new ExpectedException( - typeof(SecurityTokenReplayDetectedException), - nameof(CustomTokenReplayValidationDelegates.CustomTokenReplayValidationDelegate)), - TokenReplayValidationError = new CustomTokenReplayValidationError( - new MessageDetail( - nameof(CustomTokenReplayValidationDelegates.CustomTokenReplayValidationDelegate), null), - ValidationFailureType.TokenReplayValidationFailed, - typeof(SecurityTokenReplayDetectedException), - new StackFrame("CustomTokenReplayValidationDelegates.cs", 160), - expirationTime) - }); - - // CustomTokenReplayValidationError : TokenReplayValidationError, ExceptionType: CustomSecurityTokenReplayDetectedException : SecurityTokenReplayDetectedException - theoryData.Add(new TokenReplayExtensibilityTheoryData( - "CustomTokenReplayValidatorCustomExceptionDelegate", - utcNow, - CustomTokenReplayValidationDelegates.CustomTokenReplayValidatorCustomExceptionDelegate, - extraStackFrames: 1) - { - ExpectedException = new ExpectedException( - typeof(CustomSecurityTokenReplayDetectedException), - nameof(CustomTokenReplayValidationDelegates.CustomTokenReplayValidatorCustomExceptionDelegate)), - TokenReplayValidationError = new CustomTokenReplayValidationError( - new MessageDetail( - nameof(CustomTokenReplayValidationDelegates.CustomTokenReplayValidatorCustomExceptionDelegate), null), - ValidationFailureType.TokenReplayValidationFailed, - typeof(CustomSecurityTokenReplayDetectedException), - new StackFrame("CustomTokenReplayValidationDelegates.cs", 175), - expirationTime), - }); - - // CustomTokenReplayValidationError : TokenReplayValidationError, ExceptionType: NotSupportedException : SystemException - theoryData.Add(new TokenReplayExtensibilityTheoryData( - "CustomTokenReplayValidatorUnknownExceptionDelegate", - utcNow, - CustomTokenReplayValidationDelegates.CustomTokenReplayValidatorUnknownExceptionDelegate, - extraStackFrames: 1) - { - // CustomTokenReplayValidationError does not handle the exception type 'NotSupportedException' - ExpectedException = ExpectedException.SecurityTokenException( - LogHelper.FormatInvariant( - Tokens.LogMessages.IDX10002, // "IDX10002: Unknown exception type returned. Type: '{0}'. Message: '{1}'."; - typeof(NotSupportedException), - nameof(CustomTokenReplayValidationDelegates.CustomTokenReplayValidatorUnknownExceptionDelegate))), - TokenReplayValidationError = new CustomTokenReplayValidationError( - new MessageDetail( - nameof(CustomTokenReplayValidationDelegates.CustomTokenReplayValidatorUnknownExceptionDelegate), null), - ValidationFailureType.TokenReplayValidationFailed, - typeof(NotSupportedException), - new StackFrame("CustomTokenReplayValidationDelegates.cs", 205), - expirationTime), - }); - - // CustomTokenReplayValidationError : TokenReplayValidationError, ExceptionType: NotSupportedException : SystemException, ValidationFailureType: CustomAudienceValidationFailureType - theoryData.Add(new TokenReplayExtensibilityTheoryData( - "CustomTokenReplayValidatorCustomExceptionCustomFailureTypeDelegate", - utcNow, - CustomTokenReplayValidationDelegates.CustomTokenReplayValidatorCustomExceptionCustomFailureTypeDelegate, - extraStackFrames: 1) - { - ExpectedException = new ExpectedException( - typeof(CustomSecurityTokenReplayDetectedException), - nameof(CustomTokenReplayValidationDelegates.CustomTokenReplayValidatorCustomExceptionCustomFailureTypeDelegate)), - TokenReplayValidationError = new CustomTokenReplayValidationError( - new MessageDetail( - nameof(CustomTokenReplayValidationDelegates.CustomTokenReplayValidatorCustomExceptionCustomFailureTypeDelegate), null), - CustomTokenReplayValidationError.CustomTokenReplayValidationFailureType, - typeof(CustomSecurityTokenReplayDetectedException), - new StackFrame("CustomTokenReplayValidationDelegates.cs", 190), - expirationTime), - }); - #endregion - - #region return TokenReplayValidationError - // Test cases where delegate is overridden and return an TokenReplayValidationError - // TokenReplayValidationError : ValidationError, ExceptionType: SecurityTokenReplayDetectedException - theoryData.Add(new TokenReplayExtensibilityTheoryData( - "TokenReplayValidationDelegate", - utcNow, - CustomTokenReplayValidationDelegates.TokenReplayValidationDelegate, - extraStackFrames: 1) - { - ExpectedException = new ExpectedException( - typeof(SecurityTokenReplayDetectedException), - nameof(CustomTokenReplayValidationDelegates.TokenReplayValidationDelegate)), - TokenReplayValidationError = new TokenReplayValidationError( - new MessageDetail( - nameof(CustomTokenReplayValidationDelegates.TokenReplayValidationDelegate), null), - ValidationFailureType.TokenReplayValidationFailed, - typeof(SecurityTokenReplayDetectedException), - new StackFrame("CustomTokenReplayValidationDelegates.cs", 235), - expirationTime) - }); - - // TokenReplayValidationError : ValidationError, ExceptionType: CustomSecurityTokenReplayDetectedException : SecurityTokenReplayDetectedException - theoryData.Add(new TokenReplayExtensibilityTheoryData( - "TokenReplayValidatorCustomTokenReplayDetectedExceptionTypeDelegate", - utcNow, - CustomTokenReplayValidationDelegates.TokenReplayValidatorCustomTokenReplayDetectedExceptionTypeDelegate, - extraStackFrames: 1) - { - // TokenReplayValidationError does not handle the exception type 'CustomSecurityTokenReplayDetectedException' - ExpectedException = ExpectedException.SecurityTokenException( - LogHelper.FormatInvariant( - Tokens.LogMessages.IDX10002, // "IDX10002: Unknown exception type returned. Type: '{0}'. Message: '{1}'."; - typeof(CustomSecurityTokenReplayDetectedException), - nameof(CustomTokenReplayValidationDelegates.TokenReplayValidatorCustomTokenReplayDetectedExceptionTypeDelegate))), - TokenReplayValidationError = new TokenReplayValidationError( - new MessageDetail( - nameof(CustomTokenReplayValidationDelegates.TokenReplayValidatorCustomTokenReplayDetectedExceptionTypeDelegate), null), - ValidationFailureType.TokenReplayValidationFailed, - typeof(CustomSecurityTokenReplayDetectedException), - new StackFrame("CustomTokenReplayValidationDelegates.cs", 259), - expirationTime) - }); - - // TokenReplayValidationError : ValidationError, ExceptionType: CustomSecurityTokenException : SystemException - theoryData.Add(new TokenReplayExtensibilityTheoryData( - "TokenReplayValidatorCustomExceptionTypeDelegate", - utcNow, - CustomTokenReplayValidationDelegates.TokenReplayValidatorCustomExceptionTypeDelegate, - extraStackFrames: 1) - { - // TokenReplayValidationError does not handle the exception type 'CustomSecurityTokenException' - ExpectedException = ExpectedException.SecurityTokenException( - LogHelper.FormatInvariant( - Tokens.LogMessages.IDX10002, // "IDX10002: Unknown exception type returned. Type: '{0}'. Message: '{1}'."; - typeof(CustomSecurityTokenException), - nameof(CustomTokenReplayValidationDelegates.TokenReplayValidatorCustomExceptionTypeDelegate))), - TokenReplayValidationError = new TokenReplayValidationError( - new MessageDetail( - nameof(CustomTokenReplayValidationDelegates.TokenReplayValidatorCustomExceptionTypeDelegate), null), - ValidationFailureType.TokenReplayValidationFailed, - typeof(CustomSecurityTokenException), - new StackFrame("CustomTokenReplayValidationDelegates.cs", 274), - expirationTime) - }); - - // TokenReplayValidationError : ValidationError, ExceptionType: SecurityTokenReplayDetectedException, inner: CustomSecurityTokenReplayDetectedException - theoryData.Add(new TokenReplayExtensibilityTheoryData( - "TokenReplayValidatorThrows", - utcNow, - CustomTokenReplayValidationDelegates.TokenReplayValidatorThrows, - extraStackFrames: 0) - { - ExpectedException = new ExpectedException( - typeof(SecurityTokenReplayDetectedException), - string.Format(Tokens.LogMessages.IDX10276), - typeof(CustomSecurityTokenReplayDetectedException)), - TokenReplayValidationError = new TokenReplayValidationError( - new MessageDetail( - string.Format(Tokens.LogMessages.IDX10276), null), - ValidationFailureType.TokenReplayValidatorThrew, - typeof(SecurityTokenReplayDetectedException), - new StackFrame("SamlSecurityTokenHandler.ValidateToken.Internal.cs", 250), - expirationTime, - new SecurityTokenReplayDetectedException(nameof(CustomTokenReplayValidationDelegates.TokenReplayValidatorThrows)) - ) - }); - #endregion - - return theoryData; - } + await ExtensibilityTesting.ValidateTokenAsync_Extensibility( + theoryData, + this, + nameof(ValidateTokenAsync_TokenReplayValidator_Extensibility)); } - public class TokenReplayExtensibilityTheoryData : TheoryDataBase + public static TheoryData GenerateTokenReplayExtensibilityTestCases( + string tokenHandlerType, + int extraStackFrames) { - internal TokenReplayExtensibilityTheoryData(string testId, DateTime utcNow, TokenReplayValidationDelegate tokenReplayValidator, int extraStackFrames) : base(testId) - { - SamlToken = (SamlSecurityToken)SamlSecurityTokenHandler.CreateToken( - new SecurityTokenDescriptor() - { - Subject = Default.SamlClaimsIdentity, - Issuer = Default.Issuer, - IssuedAt = utcNow, - NotBefore = utcNow, - Expires = utcNow + TimeSpan.FromHours(1), - }); - - ValidationParameters = new ValidationParameters - { - AlgorithmValidator = SkipValidationDelegates.SkipAlgorithmValidation, - AudienceValidator = SkipValidationDelegates.SkipAudienceValidation, - IssuerValidatorAsync = SkipValidationDelegates.SkipIssuerValidation, - IssuerSigningKeyValidator = SkipValidationDelegates.SkipIssuerSigningKeyValidation, - LifetimeValidator = SkipValidationDelegates.SkipLifetimeValidation, - SignatureValidator = SkipValidationDelegates.SkipSignatureValidation, - TokenReplayValidator = tokenReplayValidator, - TokenTypeValidator = SkipValidationDelegates.SkipTokenTypeValidation - }; - - ExtraStackFrames = extraStackFrames; - } - - public SamlSecurityToken SamlToken { get; } - - public SamlSecurityTokenHandler SamlSecurityTokenHandler { get; } = new SamlSecurityTokenHandler(); - - public bool IsValid { get; set; } - - internal ValidationParameters? ValidationParameters { get; set; } - - internal TokenReplayValidationError? TokenReplayValidationError { get; set; } - - internal int ExtraStackFrames { get; } + return ExtensibilityTesting.GenerateTokenReplayExtensibilityTestCases( + tokenHandlerType, + extraStackFrames, + "SamlSecurityTokenHandler.ValidateToken.Internal.cs"); } } }