From 08365d5d0f02302104cd854b236e21245fc5d95a Mon Sep 17 00:00:00 2001 From: Franco Fung Date: Wed, 31 Jul 2024 14:29:02 -0700 Subject: [PATCH 1/3] Re-factor audience validator to use ValidatationParameters. --- .../LogMessages.cs | 2 +- .../Validation/ValidationParameters.cs | 20 +- .../Validation/Validators.Audience.cs | 73 +----- .../AudienceValidationResultTests.cs | 215 ++++-------------- .../Validation/ValidationParametersTests.cs | 19 ++ 5 files changed, 85 insertions(+), 244 deletions(-) diff --git a/src/Microsoft.IdentityModel.Tokens/LogMessages.cs b/src/Microsoft.IdentityModel.Tokens/LogMessages.cs index d7ecd84c59..f68e41dfde 100644 --- a/src/Microsoft.IdentityModel.Tokens/LogMessages.cs +++ b/src/Microsoft.IdentityModel.Tokens/LogMessages.cs @@ -36,7 +36,7 @@ internal static class LogMessages public const string IDX10208 = "IDX10208: Unable to validate audience. validationParameters.ValidAudience is null or whitespace and validationParameters.ValidAudiences is null."; public const string IDX10209 = "IDX10209: Token has length: '{0}' which is larger than the MaximumTokenSizeInBytes: '{1}'."; public const string IDX10211 = "IDX10211: Unable to validate issuer. The 'issuer' parameter is null or whitespace."; - public const string IDX10214 = "IDX10214: Audience validation failed. Audiences: '{0}'. Did not match: validationParameters.ValidAudience: '{1}' or validationParameters.ValidAudiences: '{2}'."; + public const string IDX10214 = "IDX10214: Audience validation failed. Audiences: '{0}'. Did not match: validationParameters.ValidAudiences: '{1}'."; public const string IDX10222 = "IDX10222: Lifetime validation failed. The token is not yet valid. ValidFrom (UTC): '{0}', Current time (UTC): '{1}'."; public const string IDX10223 = "IDX10223: Lifetime validation failed. The token is expired. ValidTo (UTC): '{0}', Current time (UTC): '{1}'."; public const string IDX10224 = "IDX10224: Lifetime validation failed. The NotBefore (UTC): '{0}' is after Expires (UTC): '{1}'."; diff --git a/src/Microsoft.IdentityModel.Tokens/Validation/ValidationParameters.cs b/src/Microsoft.IdentityModel.Tokens/Validation/ValidationParameters.cs index c064531798..5526cd1b7f 100644 --- a/src/Microsoft.IdentityModel.Tokens/Validation/ValidationParameters.cs +++ b/src/Microsoft.IdentityModel.Tokens/Validation/ValidationParameters.cs @@ -22,6 +22,7 @@ internal class ValidationParameters private string _roleClaimType = ClaimsIdentity.DefaultRoleClaimType; private Dictionary _instancePropertyBag; private IList _validTokenTypes = []; + private IList _validAudiences = []; private AlgorithmValidatorDelegate _algorithmValidator = Validators.ValidateAlgorithm; private AudienceValidatorDelegate _audienceValidator = Validators.ValidateAudience; @@ -513,9 +514,14 @@ public TypeValidatorDelegate TypeValidator /// /// Gets the that contains valid audiences that will be used to check against the token's audience. - /// The default is null. + /// The default is an empty collection. /// - public IList ValidAudiences { get; } + /// Thrown when the value is set as null. + public IList ValidAudiences + { + get { return _validAudiences; } + set { _validAudiences = value ?? throw new ArgumentNullException(nameof(value), "ValidAudiences cannot be set as null."); } + } /// /// Gets the that contains valid issuers that will be used to check against the token's issuer. @@ -533,14 +539,8 @@ public TypeValidatorDelegate TypeValidator /// The that contains valid token types that will be used to check against the token's 'typ' claim. public IList ValidTypes { - get - { - return _validTokenTypes; - } - set - { - _validTokenTypes = value ?? throw new ArgumentNullException(nameof(value)); - } + get { return _validTokenTypes; } + set { _validTokenTypes = value ?? throw new ArgumentNullException(nameof(value), "ValidTypes cannot be set as null."); } } public bool ValidateActor { get; set; } diff --git a/src/Microsoft.IdentityModel.Tokens/Validation/Validators.Audience.cs b/src/Microsoft.IdentityModel.Tokens/Validation/Validators.Audience.cs index 1630c221b8..9f463bf803 100644 --- a/src/Microsoft.IdentityModel.Tokens/Validation/Validators.Audience.cs +++ b/src/Microsoft.IdentityModel.Tokens/Validation/Validators.Audience.cs @@ -21,9 +21,9 @@ namespace Microsoft.IdentityModel.Tokens /// A that contains the results of validating the issuer. /// This delegate is not expected to throw. internal delegate AudienceValidationResult AudienceValidatorDelegate( - IEnumerable audiences, + IList audiences, SecurityToken? securityToken, - TokenValidationParameters validationParameters, + ValidationParameters validationParameters, CallContext callContext); /// @@ -44,7 +44,7 @@ public static partial class Validators /// If none of the 'audiences' matched either or one of . /// An EXACT match is required. #pragma warning disable CA1801 // TODO: remove pragma disable once callContext is used for logging - internal static AudienceValidationResult ValidateAudience(IEnumerable audiences, SecurityToken? securityToken, TokenValidationParameters validationParameters, CallContext callContext) + internal static AudienceValidationResult ValidateAudience(IList audiences, SecurityToken? securityToken, ValidationParameters validationParameters, CallContext callContext) #pragma warning restore CA1801 { if (validationParameters == null) @@ -58,12 +58,6 @@ internal static AudienceValidationResult ValidateAudience(IEnumerable au typeof(ArgumentNullException), new StackFrame(true))); - if (!validationParameters.ValidateAudience) - { - LogHelper.LogWarning(LogMessages.IDX10233); - return new AudienceValidationResult(Utility.SerializeAsSingleCommaDelimitedString(audiences)); - } - if (audiences == null) return new AudienceValidationResult( Utility.SerializeAsSingleCommaDelimitedString(audiences), @@ -75,24 +69,10 @@ internal static AudienceValidationResult ValidateAudience(IEnumerable au typeof(SecurityTokenInvalidAudienceException), new StackFrame(true))); - if (string.IsNullOrWhiteSpace(validationParameters.ValidAudience) && (validationParameters.ValidAudiences == null)) + if (audiences.Count == 0) return new AudienceValidationResult( Utility.SerializeAsSingleCommaDelimitedString(audiences), ValidationFailureType.NullArgument, - new ExceptionDetail( - new MessageDetail( - LogMessages.IDX10208, - null), - typeof(SecurityTokenInvalidAudienceException), - new StackFrame(true))); - - if (audiences is not List audiencesAsList) - audiencesAsList = audiences.ToList(); - - if (audiencesAsList.Count == 0) - return new AudienceValidationResult( - Utility.SerializeAsSingleCommaDelimitedString(audiencesAsList), - ValidationFailureType.NullArgument, new ExceptionDetail( new MessageDetail( LogMessages.IDX10206, @@ -100,67 +80,34 @@ internal static AudienceValidationResult ValidateAudience(IEnumerable au typeof(SecurityTokenInvalidAudienceException), new StackFrame(true))); - string? validAudience = AudienceIsValidReturning(audiencesAsList, validationParameters); + string? validAudience = AudienceIsValidReturning((List)audiences, validationParameters); if (validAudience != null) { return new AudienceValidationResult(validAudience); } return new AudienceValidationResult( - Utility.SerializeAsSingleCommaDelimitedString(audiencesAsList), + Utility.SerializeAsSingleCommaDelimitedString(audiences), ValidationFailureType.AudienceValidationFailed, new ExceptionDetail( new MessageDetail( LogMessages.IDX10214, - LogHelper.MarkAsNonPII(Utility.SerializeAsSingleCommaDelimitedString(audiencesAsList)), - LogHelper.MarkAsNonPII(validationParameters.ValidAudience ?? "null"), + LogHelper.MarkAsNonPII(Utility.SerializeAsSingleCommaDelimitedString(audiences)), LogHelper.MarkAsNonPII(Utility.SerializeAsSingleCommaDelimitedString(validationParameters.ValidAudiences))), typeof(SecurityTokenInvalidAudienceException), new StackFrame(true))); } - private static bool AudienceIsValid(List audiences, TokenValidationParameters validationParameters) - { - return AudienceIsValidReturning(audiences, validationParameters) != null; - } - - private static string? AudienceIsValidReturning(List audiences, TokenValidationParameters validationParameters) + private static string? AudienceIsValidReturning(List audiences, ValidationParameters validationParameters) { string? validAudience = null; - if (!string.IsNullOrWhiteSpace(validationParameters.ValidAudience)) - validAudience = AudiencesMatchSingle(audiences, validationParameters.ValidAudience, validationParameters.IgnoreTrailingSlashWhenValidatingAudience); - - if (validAudience == null && validationParameters.ValidAudiences != null) - { - if (validationParameters.ValidAudiences is not List validAudiences) - validAudiences = validationParameters.ValidAudiences.ToList(); - validAudience = AudiencesMatchList(audiences, validAudiences, validationParameters.IgnoreTrailingSlashWhenValidatingAudience); - } + List validAudiences = validationParameters.ValidAudiences.ToList(); + validAudience = AudiencesMatchList(audiences, validAudiences, validationParameters.IgnoreTrailingSlashWhenValidatingAudience); return validAudience; } - private static string? AudiencesMatchSingle(List audiences, string validAudience, bool ignoreTrailingSlashWhenValidatingAudience) - { - for (int i = 0; i < audiences.Count; i++) - { - string tokenAudience = audiences[i]; - if (string.IsNullOrWhiteSpace(tokenAudience)) - continue; - - if (AudiencesMatch(ignoreTrailingSlashWhenValidatingAudience, tokenAudience, validAudience)) - { - if (LogHelper.IsEnabled(EventLogLevel.Informational)) - LogHelper.LogInformation(LogMessages.IDX10234, LogHelper.MarkAsNonPII(tokenAudience)); - - return tokenAudience; - } - } - - return null; - } - private static string? AudiencesMatchList(IList audiences, List validAudiences, bool ignoreTrailingSlashWhenValidatingAudience) { for (int i = 0; i < audiences.Count; i++) diff --git a/test/Microsoft.IdentityModel.Tokens.Tests/Validation/AudienceValidationResultTests.cs b/test/Microsoft.IdentityModel.Tokens.Tests/Validation/AudienceValidationResultTests.cs index aa6a45b784..aa38c58c24 100644 --- a/test/Microsoft.IdentityModel.Tokens.Tests/Validation/AudienceValidationResultTests.cs +++ b/test/Microsoft.IdentityModel.Tokens.Tests/Validation/AudienceValidationResultTests.cs @@ -62,44 +62,6 @@ public static TheoryData ValidateAudienceParameter null)), }, new AudienceValidationTheoryData - { - Audiences = new List { "" }, - ExpectedException = ExpectedException.SecurityTokenInvalidAudienceException("IDX10214:"), - TestId = "AudiencesEmptyString", - ValidationParameters = new TokenValidationParameters{ ValidAudience = "audience"}, - AudienceValidationResult = new AudienceValidationResult( - "", - ValidationFailureType.NullArgument, - new ExceptionDetail( - new MessageDetail( - LogMessages.IDX10214, - LogHelper.MarkAsNonPII(""), - LogHelper.MarkAsNonPII("audience"), - LogHelper.MarkAsNonPII("null")), - typeof(SecurityTokenInvalidAudienceException), - new StackFrame(true), - null)), - }, - new AudienceValidationTheoryData - { - Audiences = new List { " " }, - ExpectedException = ExpectedException.SecurityTokenInvalidAudienceException("IDX10214:"), - TestId = "AudiencesWhiteSpace", - ValidationParameters = new TokenValidationParameters{ ValidAudience = "audience"}, - AudienceValidationResult = new AudienceValidationResult( - " ", - ValidationFailureType.NullArgument, - new ExceptionDetail( - new MessageDetail( - LogMessages.IDX10214, - LogHelper.MarkAsNonPII(" "), - LogHelper.MarkAsNonPII("audience"), - LogHelper.MarkAsNonPII("null")), - typeof(SecurityTokenInvalidAudienceException), - new StackFrame(true), - null)), - }, - new AudienceValidationTheoryData { Audiences = null, ExpectedException = ExpectedException.SecurityTokenInvalidAudienceException("IDX10207:"), @@ -120,7 +82,7 @@ public static TheoryData ValidateAudienceParameter Audiences = new List{ }, ExpectedException = ExpectedException.SecurityTokenInvalidAudienceException("IDX10206:"), TestId = "AudiencesEmptyList", - ValidationParameters = new TokenValidationParameters{ ValidAudience = "audience"}, + ValidationParameters = new ValidationParameters(), AudienceValidationResult = new AudienceValidationResult( "empty", ValidationFailureType.NullArgument, @@ -133,59 +95,11 @@ public static TheoryData ValidateAudienceParameter null)), }, new AudienceValidationTheoryData - { - Audiences = new List{ }, - TestId = "ValidateAudienceFalseAudiencesEmptyList", - ValidationParameters = new TokenValidationParameters{ ValidateAudience = false }, - AudienceValidationResult = new AudienceValidationResult("empty") - }, - new AudienceValidationTheoryData - { - Audiences = null, - TestId = "ValidateAudienceFalseAudiencesNull", - ValidationParameters = new TokenValidationParameters{ ValidateAudience = false }, - AudienceValidationResult = new AudienceValidationResult("null") - }, - new AudienceValidationTheoryData - { - Audiences = new List { "audience1" }, - ExpectedException = ExpectedException.SecurityTokenInvalidAudienceException("IDX10208:"), - TestId = "ValidAudienceEmptyString", - ValidationParameters = new TokenValidationParameters{ ValidAudience = "" }, - AudienceValidationResult = new AudienceValidationResult( - "audience1", - ValidationFailureType.NullArgument, - new ExceptionDetail( - new MessageDetail( - LogMessages.IDX10208, - null), - typeof(SecurityTokenInvalidAudienceException), - new StackFrame(true), - null)), - }, - new AudienceValidationTheoryData - { - Audiences = new List { "audience1" }, - ExpectedException = ExpectedException.SecurityTokenInvalidAudienceException("IDX10208:"), - TestId = "ValidAudienceWhiteSpace", - ValidationParameters = new TokenValidationParameters{ ValidAudience = " " }, - AudienceValidationResult = new AudienceValidationResult( - "audience1", - ValidationFailureType.NullArgument, - new ExceptionDetail( - new MessageDetail( - LogMessages.IDX10208, - null), - typeof(SecurityTokenInvalidAudienceException), - new StackFrame(true), - null)), - }, - new AudienceValidationTheoryData { Audiences = new List { "audience1" }, ExpectedException = ExpectedException.SecurityTokenInvalidAudienceException("IDX10214:"), TestId = "ValidAudiencesEmptyString", - ValidationParameters = new TokenValidationParameters{ ValidAudiences = new List{ "" } }, + ValidationParameters = new ValidationParameters{ ValidAudiences = [String.Empty] }, AudienceValidationResult = new AudienceValidationResult( "audience1", ValidationFailureType.NullArgument, @@ -193,8 +107,7 @@ public static TheoryData ValidateAudienceParameter new MessageDetail( LogMessages.IDX10214, LogHelper.MarkAsNonPII("audience1"), - LogHelper.MarkAsNonPII("null"), - LogHelper.MarkAsNonPII("")), + LogHelper.MarkAsNonPII(String.Empty)), typeof(SecurityTokenInvalidAudienceException), new StackFrame(true), null)), @@ -204,7 +117,7 @@ public static TheoryData ValidateAudienceParameter Audiences = new List { "audience1" }, ExpectedException = ExpectedException.SecurityTokenInvalidAudienceException("IDX10214:"), TestId = "ValidAudiencesWhiteSpace", - ValidationParameters = new TokenValidationParameters{ ValidAudiences = new List{ " " } }, + ValidationParameters = new ValidationParameters{ ValidAudiences = [" "] }, AudienceValidationResult = new AudienceValidationResult( "audience1", ValidationFailureType.NullArgument, @@ -212,27 +125,10 @@ public static TheoryData ValidateAudienceParameter new MessageDetail( LogMessages.IDX10214, LogHelper.MarkAsNonPII("audience1"), - LogHelper.MarkAsNonPII("null"), LogHelper.MarkAsNonPII(" ")), typeof(SecurityTokenInvalidAudienceException), new StackFrame(true), null)), - }, - new AudienceValidationTheoryData - { - Audiences = new List { "audience1" }, - ExpectedException = ExpectedException.SecurityTokenInvalidAudienceException("IDX10208:"), - TestId = "ValidateAudienceTrueValidAudienceAndValidAudiencesNull", - AudienceValidationResult = new AudienceValidationResult( - "audience1", - ValidationFailureType.NullArgument, - new ExceptionDetail( - new MessageDetail( - LogMessages.IDX10208, - null), - typeof(SecurityTokenInvalidAudienceException), - new StackFrame(true), - null)), } }; } @@ -286,7 +182,7 @@ public static TheoryData ValidateAudienceTheoryDat { Audiences = audiences1, TestId = "SameLengthMatched", - ValidationParameters = new TokenValidationParameters{ ValidAudience = audience1 }, + ValidationParameters = new ValidationParameters{ ValidAudiences = [audience1] }, SecurityToken = JsonUtilities.CreateUnsignedJsonWebToken(JwtRegisteredClaimNames.Iss, "Issuer"), AudienceValidationResult = new AudienceValidationResult(audience1) }, @@ -295,7 +191,7 @@ public static TheoryData ValidateAudienceTheoryDat Audiences = audiences1, ExpectedException = ExpectedException.SecurityTokenInvalidAudienceException("IDX10214:"), TestId = "SameLengthNotMatched", - ValidationParameters = new TokenValidationParameters{ ValidAudience = audience2 }, + ValidationParameters = new ValidationParameters{ ValidAudiences = [audience2] }, SecurityToken = JsonUtilities.CreateUnsignedJsonWebToken(JwtRegisteredClaimNames.Iss, "Issuer"), AudienceValidationResult = new AudienceValidationResult( commaAudience1, @@ -304,26 +200,17 @@ public static TheoryData ValidateAudienceTheoryDat new MessageDetail( LogMessages.IDX10214, LogHelper.MarkAsNonPII(commaAudience1), - LogHelper.MarkAsNonPII(audience2), - LogHelper.MarkAsNonPII("null")), + LogHelper.MarkAsNonPII(audience2)), typeof(SecurityTokenInvalidAudienceException), new StackFrame(true), null)), }, new AudienceValidationTheoryData - { - Audiences = audiences1, - TestId = "NoMatchTVPValidateFalse", - ValidationParameters = new TokenValidationParameters{ ValidAudience = audience2, ValidateAudience = false }, - SecurityToken = JsonUtilities.CreateUnsignedJsonWebToken(JwtRegisteredClaimNames.Iss, "Issuer"), - AudienceValidationResult = new AudienceValidationResult(commaAudience1) - }, - new AudienceValidationTheoryData { Audiences = audiences1, ExpectedException = ExpectedException.SecurityTokenInvalidAudienceException("IDX10214:"), TestId = "AudiencesValidAudienceWithSlashNotMatched", - ValidationParameters = new TokenValidationParameters{ ValidAudience = audience2 + "/" }, + ValidationParameters = new ValidationParameters{ ValidAudiences = [audience2 + "/"] }, SecurityToken = JsonUtilities.CreateUnsignedJsonWebToken(JwtRegisteredClaimNames.Iss, "Issuer"), AudienceValidationResult = new AudienceValidationResult( commaAudience1, @@ -332,8 +219,7 @@ public static TheoryData ValidateAudienceTheoryDat new MessageDetail( LogMessages.IDX10214, LogHelper.MarkAsNonPII(commaAudience1), - LogHelper.MarkAsNonPII(audience2Slash), - LogHelper.MarkAsNonPII("null")), + LogHelper.MarkAsNonPII(audience2Slash)), typeof(SecurityTokenInvalidAudienceException), new StackFrame(true), null)), @@ -343,7 +229,7 @@ public static TheoryData ValidateAudienceTheoryDat Audiences = audiences2WithSlash, ExpectedException = ExpectedException.SecurityTokenInvalidAudienceException("IDX10214:"), TestId = "AudiencesWithSlashValidAudienceSameLengthNotMatched", - ValidationParameters = new TokenValidationParameters{ ValidAudience = audience1 }, + ValidationParameters = new ValidationParameters{ ValidAudiences = [audience1] }, AudienceValidationResult = new AudienceValidationResult( commaAudience2Slash, ValidationFailureType.NullArgument, @@ -351,8 +237,7 @@ public static TheoryData ValidateAudienceTheoryDat new MessageDetail( LogMessages.IDX10214, LogHelper.MarkAsNonPII(commaAudience2Slash), - LogHelper.MarkAsNonPII(audience1), - LogHelper.MarkAsNonPII("null")), + LogHelper.MarkAsNonPII(audience1)), typeof(SecurityTokenInvalidAudienceException), new StackFrame(true), null)), @@ -361,8 +246,8 @@ public static TheoryData ValidateAudienceTheoryDat { Audiences = audiences1, ExpectedException = ExpectedException.SecurityTokenInvalidAudienceException("IDX10214:"), - TestId = "ValidAudienceWithSlashTVPFalse", - ValidationParameters = new TokenValidationParameters{ IgnoreTrailingSlashWhenValidatingAudience = false, ValidAudience = audience1 + "/" }, + TestId = "ValidAudienceWithSlashVPFalse", + ValidationParameters = new ValidationParameters{ IgnoreTrailingSlashWhenValidatingAudience = false, ValidAudiences = [audience1 + "/"] }, AudienceValidationResult = new AudienceValidationResult( commaAudience1, ValidationFailureType.NullArgument, @@ -370,8 +255,7 @@ public static TheoryData ValidateAudienceTheoryDat new MessageDetail( LogMessages.IDX10214, LogHelper.MarkAsNonPII(commaAudience1), - LogHelper.MarkAsNonPII(audience1Slash), - LogHelper.MarkAsNonPII("null")), + LogHelper.MarkAsNonPII(audience1Slash)), typeof(SecurityTokenInvalidAudienceException), new StackFrame(true), null)), @@ -379,16 +263,16 @@ public static TheoryData ValidateAudienceTheoryDat new AudienceValidationTheoryData { Audiences = audiences1, - TestId = "ValidAudienceWithSlashTVPTrue", - ValidationParameters = new TokenValidationParameters{ ValidAudience = audience1 + "/" }, + TestId = "ValidAudienceWithSlashVPTrue", + ValidationParameters = new ValidationParameters{ ValidAudiences = [audience1 + "/"] }, AudienceValidationResult = new AudienceValidationResult(audience1) }, new AudienceValidationTheoryData { Audiences = audiences1, ExpectedException = ExpectedException.SecurityTokenInvalidAudienceException("IDX10214:"), - TestId = "ValidAudiencesWithSlashTVPFalse", - ValidationParameters = new TokenValidationParameters{ IgnoreTrailingSlashWhenValidatingAudience = false, ValidAudiences = audiences1WithSlash }, + TestId = "ValidAudiencesWithSlashVPFalse", + ValidationParameters = new ValidationParameters{ IgnoreTrailingSlashWhenValidatingAudience = false, ValidAudiences = audiences1WithSlash }, AudienceValidationResult = new AudienceValidationResult( commaAudience1, ValidationFailureType.NullArgument, @@ -396,7 +280,6 @@ public static TheoryData ValidateAudienceTheoryDat new MessageDetail( LogMessages.IDX10214, LogHelper.MarkAsNonPII(commaAudience1), - LogHelper.MarkAsNonPII("null"), LogHelper.MarkAsNonPII(commaAudience1Slash)), typeof(SecurityTokenInvalidAudienceException), new StackFrame(true), @@ -405,8 +288,8 @@ public static TheoryData ValidateAudienceTheoryDat new AudienceValidationTheoryData { Audiences = audiences1, - TestId = "ValidAudiencesWithSlashTVPTrue", - ValidationParameters = new TokenValidationParameters{ ValidAudiences = audiences1WithSlash }, + TestId = "ValidAudiencesWithSlashVPTrue", + ValidationParameters = new ValidationParameters{ ValidAudiences = audiences1WithSlash }, AudienceValidationResult = new AudienceValidationResult(audience1) }, new AudienceValidationTheoryData @@ -414,7 +297,7 @@ public static TheoryData ValidateAudienceTheoryDat Audiences = audiences1, ExpectedException = ExpectedException.SecurityTokenInvalidAudienceException("IDX10214:"), TestId = "ValidAudienceWithExtraChar", - ValidationParameters = new TokenValidationParameters{ ValidAudience = audience1 + "A" }, + ValidationParameters = new ValidationParameters{ ValidAudiences = [audience1 + "A"] }, AudienceValidationResult = new AudienceValidationResult( commaAudience1, ValidationFailureType.NullArgument, @@ -422,8 +305,7 @@ public static TheoryData ValidateAudienceTheoryDat new MessageDetail( LogMessages.IDX10214, LogHelper.MarkAsNonPII(commaAudience1), - LogHelper.MarkAsNonPII(audience1 + "A"), - LogHelper.MarkAsNonPII("null")), + LogHelper.MarkAsNonPII(audience1 + "A")), typeof(SecurityTokenInvalidAudienceException), new StackFrame(true), null)), @@ -432,8 +314,8 @@ public static TheoryData ValidateAudienceTheoryDat { Audiences = audiences1, ExpectedException = ExpectedException.SecurityTokenInvalidAudienceException("IDX10214:"), - TestId = "ValidAudienceWithDoubleSlashTVPTrue", - ValidationParameters = new TokenValidationParameters{ ValidAudience = audience1 + "//" }, + TestId = "ValidAudienceWithDoubleSlashVPTrue", + ValidationParameters = new ValidationParameters{ ValidAudiences = [audience1 + "//"] }, AudienceValidationResult = new AudienceValidationResult( commaAudience1, ValidationFailureType.NullArgument, @@ -441,8 +323,7 @@ public static TheoryData ValidateAudienceTheoryDat new MessageDetail( LogMessages.IDX10214, LogHelper.MarkAsNonPII(commaAudience1), - LogHelper.MarkAsNonPII(audience1 + "//"), - LogHelper.MarkAsNonPII("null")), + LogHelper.MarkAsNonPII(audience1 + "//")), typeof(SecurityTokenInvalidAudienceException), new StackFrame(true), null)), @@ -451,8 +332,8 @@ public static TheoryData ValidateAudienceTheoryDat { Audiences = audiences1, ExpectedException = ExpectedException.SecurityTokenInvalidAudienceException("IDX10214:"), - TestId = "ValidAudiencesWithDoubleSlashTVPTrue", - ValidationParameters = new TokenValidationParameters{ ValidAudiences = audiences1WithTwoSlashes }, + TestId = "ValidAudiencesWithDoubleSlashVPTrue", + ValidationParameters = new ValidationParameters{ ValidAudiences = audiences1WithTwoSlashes }, AudienceValidationResult = new AudienceValidationResult( commaAudience1, ValidationFailureType.NullArgument, @@ -460,7 +341,6 @@ public static TheoryData ValidateAudienceTheoryDat new MessageDetail( LogMessages.IDX10214, LogHelper.MarkAsNonPII(commaAudience1), - LogHelper.MarkAsNonPII("null"), LogHelper.MarkAsNonPII(commaAudience1 + "//")), typeof(SecurityTokenInvalidAudienceException), new StackFrame(true), @@ -470,8 +350,8 @@ public static TheoryData ValidateAudienceTheoryDat { Audiences = audiences1WithSlash, ExpectedException = ExpectedException.SecurityTokenInvalidAudienceException("IDX10214:"), - TestId = "TokenAudienceWithSlashTVPFalse", - ValidationParameters = new TokenValidationParameters{ IgnoreTrailingSlashWhenValidatingAudience = false, ValidAudience = audience1 }, + TestId = "TokenAudienceWithSlashVPFalse", + ValidationParameters = new ValidationParameters{ IgnoreTrailingSlashWhenValidatingAudience = false, ValidAudiences = [audience1] }, AudienceValidationResult = new AudienceValidationResult( commaAudience1Slash, ValidationFailureType.NullArgument, @@ -479,8 +359,7 @@ public static TheoryData ValidateAudienceTheoryDat new MessageDetail( LogMessages.IDX10214, LogHelper.MarkAsNonPII(commaAudience1Slash), - LogHelper.MarkAsNonPII(audience1), - LogHelper.MarkAsNonPII("null")), + LogHelper.MarkAsNonPII(audience1)), typeof(SecurityTokenInvalidAudienceException), new StackFrame(true), null)), @@ -488,8 +367,8 @@ public static TheoryData ValidateAudienceTheoryDat new AudienceValidationTheoryData { Audiences = audiences1WithSlash, - TestId = "TokenAudienceWithSlashTVPTrue", - ValidationParameters = new TokenValidationParameters{ ValidAudience = audience1 }, + TestId = "TokenAudienceWithSlashVPTrue", + ValidationParameters = new ValidationParameters{ ValidAudiences = [audience1] }, AudienceValidationResult = new AudienceValidationResult(audience1Slash) }, new AudienceValidationTheoryData @@ -497,7 +376,7 @@ public static TheoryData ValidateAudienceTheoryDat Audiences = audiences2WithSlash, ExpectedException = ExpectedException.SecurityTokenInvalidAudienceException("IDX10214:"), TestId = "TokenAudienceWithSlashNotEqual", - ValidationParameters = new TokenValidationParameters{ ValidAudience = audience1 }, + ValidationParameters = new ValidationParameters{ ValidAudiences = [audience1] }, AudienceValidationResult = new AudienceValidationResult( commaAudience2Slash, ValidationFailureType.NullArgument, @@ -505,8 +384,7 @@ public static TheoryData ValidateAudienceTheoryDat new MessageDetail( LogMessages.IDX10214, LogHelper.MarkAsNonPII(commaAudience2Slash), - LogHelper.MarkAsNonPII(audience1), - LogHelper.MarkAsNonPII("null")), + LogHelper.MarkAsNonPII(audience1)), typeof(SecurityTokenInvalidAudienceException), new StackFrame(true), null)), @@ -515,8 +393,8 @@ public static TheoryData ValidateAudienceTheoryDat { Audiences = audiences1WithSlash, ExpectedException = ExpectedException.SecurityTokenInvalidAudienceException("IDX10214:"), - TestId = "TokenAudiencesWithSlashTVPFalse", - ValidationParameters = new TokenValidationParameters{ IgnoreTrailingSlashWhenValidatingAudience = false, ValidAudience = audience1 }, + TestId = "TokenAudiencesWithSlashVPFalse", + ValidationParameters = new ValidationParameters{ IgnoreTrailingSlashWhenValidatingAudience = false, ValidAudiences = [audience1] }, AudienceValidationResult = new AudienceValidationResult( commaAudience1Slash, ValidationFailureType.NullArgument, @@ -524,8 +402,7 @@ public static TheoryData ValidateAudienceTheoryDat new MessageDetail( LogMessages.IDX10214, LogHelper.MarkAsNonPII(commaAudience1Slash), - LogHelper.MarkAsNonPII(audience1), - LogHelper.MarkAsNonPII("null")), + LogHelper.MarkAsNonPII(audience1)), typeof(SecurityTokenInvalidAudienceException), new StackFrame(true), null)), @@ -533,16 +410,16 @@ public static TheoryData ValidateAudienceTheoryDat new AudienceValidationTheoryData { Audiences = audiences1WithSlash, - TestId = "TokenAudiencesWithSlashTVPTrue", - ValidationParameters = new TokenValidationParameters{ ValidAudience = audience1 }, + TestId = "TokenAudiencesWithSlashVPTrue", + ValidationParameters = new ValidationParameters{ ValidAudiences = [audience1] }, AudienceValidationResult = new AudienceValidationResult(audience1Slash) }, new AudienceValidationTheoryData { Audiences = audiences1WithSlash, ExpectedException = ExpectedException.SecurityTokenInvalidAudienceException("IDX10214:"), - TestId = "TokenAudiencesWithSlashValidAudiencesNotMatchedTVPTrue", - ValidationParameters = new TokenValidationParameters{ ValidAudiences = audiences2 }, + TestId = "TokenAudiencesWithSlashValidAudiencesNotMatchedVPTrue", + ValidationParameters = new ValidationParameters{ ValidAudiences = audiences2 }, AudienceValidationResult = new AudienceValidationResult( commaAudience1Slash, ValidationFailureType.NullArgument, @@ -550,7 +427,6 @@ public static TheoryData ValidateAudienceTheoryDat new MessageDetail( LogMessages.IDX10214, LogHelper.MarkAsNonPII(commaAudience1Slash), - LogHelper.MarkAsNonPII("null"), LogHelper.MarkAsNonPII(commaAudience2)), typeof(SecurityTokenInvalidAudienceException), new StackFrame(true), @@ -560,8 +436,8 @@ public static TheoryData ValidateAudienceTheoryDat { Audiences = audiences1WithTwoSlashes, ExpectedException = ExpectedException.SecurityTokenInvalidAudienceException("IDX10214:"), - TestId = "TokenAudienceWithTwoSlashesTVPTrue", - ValidationParameters = new TokenValidationParameters{ ValidAudience = audience1 }, + TestId = "TokenAudienceWithTwoSlashesVPTrue", + ValidationParameters = new ValidationParameters{ ValidAudiences = [audience1] }, AudienceValidationResult = new AudienceValidationResult( commaAudience1 + "//", ValidationFailureType.NullArgument, @@ -569,8 +445,7 @@ public static TheoryData ValidateAudienceTheoryDat new MessageDetail( LogMessages.IDX10214, LogHelper.MarkAsNonPII(commaAudience1 + "//"), - LogHelper.MarkAsNonPII(audience1), - LogHelper.MarkAsNonPII("null")), + LogHelper.MarkAsNonPII(audience1)), typeof(SecurityTokenInvalidAudienceException), new StackFrame(true), null)), @@ -587,7 +462,7 @@ public class AudienceValidationTheoryData : TheoryDataBase public SecurityToken SecurityToken { get; set; } - public TokenValidationParameters ValidationParameters { get; set; } = new TokenValidationParameters(); + internal ValidationParameters ValidationParameters { get; set; } = new ValidationParameters(); internal ValidationFailureType ValidationFailureType { get; set; } } diff --git a/test/Microsoft.IdentityModel.Tokens.Tests/Validation/ValidationParametersTests.cs b/test/Microsoft.IdentityModel.Tokens.Tests/Validation/ValidationParametersTests.cs index 7d1a98de4f..17a3c3fee6 100644 --- a/test/Microsoft.IdentityModel.Tokens.Tests/Validation/ValidationParametersTests.cs +++ b/test/Microsoft.IdentityModel.Tokens.Tests/Validation/ValidationParametersTests.cs @@ -20,6 +20,25 @@ public void SetValidators_NullValue_ThrowsArgumentNullException() Assert.Throws(() => validationParameters.AudienceValidator = null); } + [Fact] + public void ValidAudiences_GetSet_ValidValue_Success() + { + var validationParameters = new ValidationParameters(); + var validAudiences = new List { "audience1", "audience2" }; + + validationParameters.ValidAudiences = validAudiences; + + Assert.Equal(validAudiences, validationParameters.ValidAudiences); + } + + [Fact] + public void ValidAudiences_SetNull_ThrowsArgumentNullException() + { + var validationParameters = new ValidationParameters(); + + Assert.Throws(() => validationParameters.ValidAudiences = null); + } + [Fact] public void ValidTypes_Get_ReturnsValidTokenTypes() { From d4e57b165dd72b7056a398149b7356a06f7527ce Mon Sep 17 00:00:00 2001 From: Franco Fung Date: Wed, 31 Jul 2024 16:58:46 -0700 Subject: [PATCH 2/3] Addressing feedback --- .../LogMessages.cs | 3 +- .../Validation/Validators.Audience.cs | 12 ++-- .../AudienceValidationResultTests.cs | 60 +++++++++---------- 3 files changed, 38 insertions(+), 37 deletions(-) diff --git a/src/Microsoft.IdentityModel.Tokens/LogMessages.cs b/src/Microsoft.IdentityModel.Tokens/LogMessages.cs index f68e41dfde..2c8d35c273 100644 --- a/src/Microsoft.IdentityModel.Tokens/LogMessages.cs +++ b/src/Microsoft.IdentityModel.Tokens/LogMessages.cs @@ -36,7 +36,8 @@ internal static class LogMessages public const string IDX10208 = "IDX10208: Unable to validate audience. validationParameters.ValidAudience is null or whitespace and validationParameters.ValidAudiences is null."; public const string IDX10209 = "IDX10209: Token has length: '{0}' which is larger than the MaximumTokenSizeInBytes: '{1}'."; public const string IDX10211 = "IDX10211: Unable to validate issuer. The 'issuer' parameter is null or whitespace."; - public const string IDX10214 = "IDX10214: Audience validation failed. Audiences: '{0}'. Did not match: validationParameters.ValidAudiences: '{1}'."; + public const string IDX10214 = "IDX10214: Audience validation failed. Audiences: '{0}'. Did not match: validationParameters.ValidAudience: '{1}' or validationParameters.ValidAudiences: '{2}'."; + public const string IDX10215 = "IDX10215: Audience validation failed. Audiences: '{0}'. Did not match: validationParameters.ValidAudiences: '{1}'."; public const string IDX10222 = "IDX10222: Lifetime validation failed. The token is not yet valid. ValidFrom (UTC): '{0}', Current time (UTC): '{1}'."; public const string IDX10223 = "IDX10223: Lifetime validation failed. The token is expired. ValidTo (UTC): '{0}', Current time (UTC): '{1}'."; public const string IDX10224 = "IDX10224: Lifetime validation failed. The NotBefore (UTC): '{0}' is after Expires (UTC): '{1}'."; diff --git a/src/Microsoft.IdentityModel.Tokens/Validation/Validators.Audience.cs b/src/Microsoft.IdentityModel.Tokens/Validation/Validators.Audience.cs index 9f463bf803..5f5911dba5 100644 --- a/src/Microsoft.IdentityModel.Tokens/Validation/Validators.Audience.cs +++ b/src/Microsoft.IdentityModel.Tokens/Validation/Validators.Audience.cs @@ -91,7 +91,7 @@ internal static AudienceValidationResult ValidateAudience(IList audience ValidationFailureType.AudienceValidationFailed, new ExceptionDetail( new MessageDetail( - LogMessages.IDX10214, + LogMessages.IDX10215, LogHelper.MarkAsNonPII(Utility.SerializeAsSingleCommaDelimitedString(audiences)), LogHelper.MarkAsNonPII(Utility.SerializeAsSingleCommaDelimitedString(validationParameters.ValidAudiences))), typeof(SecurityTokenInvalidAudienceException), @@ -102,7 +102,7 @@ internal static AudienceValidationResult ValidateAudience(IList audience { string? validAudience = null; - List validAudiences = validationParameters.ValidAudiences.ToList(); + List validAudiences = [.. validationParameters.ValidAudiences]; validAudience = AudiencesMatchList(audiences, validAudiences, validationParameters.IgnoreTrailingSlashWhenValidatingAudience); return validAudience; @@ -113,15 +113,15 @@ internal static AudienceValidationResult ValidateAudience(IList audience for (int i = 0; i < audiences.Count; i++) { string tokenAudience = audiences[i]; - if (string.IsNullOrWhiteSpace(tokenAudience)) + if (string.IsNullOrEmpty(tokenAudience)) continue; - foreach (string validAudience in validAudiences) + for (int j = 0; j < validAudiences.Count; j++) { - if (string.IsNullOrEmpty(validAudience)) + if (string.IsNullOrEmpty(validAudiences[j])) continue; - if (AudiencesMatch(ignoreTrailingSlashWhenValidatingAudience, tokenAudience, validAudience)) + if (AudiencesMatch(ignoreTrailingSlashWhenValidatingAudience, tokenAudience, validAudiences[j])) { if (LogHelper.IsEnabled(EventLogLevel.Informational)) LogHelper.LogInformation(LogMessages.IDX10234, LogHelper.MarkAsNonPII(tokenAudience)); diff --git a/test/Microsoft.IdentityModel.Tokens.Tests/Validation/AudienceValidationResultTests.cs b/test/Microsoft.IdentityModel.Tokens.Tests/Validation/AudienceValidationResultTests.cs index aa38c58c24..578a638893 100644 --- a/test/Microsoft.IdentityModel.Tokens.Tests/Validation/AudienceValidationResultTests.cs +++ b/test/Microsoft.IdentityModel.Tokens.Tests/Validation/AudienceValidationResultTests.cs @@ -97,7 +97,7 @@ public static TheoryData ValidateAudienceParameter new AudienceValidationTheoryData { Audiences = new List { "audience1" }, - ExpectedException = ExpectedException.SecurityTokenInvalidAudienceException("IDX10214:"), + ExpectedException = ExpectedException.SecurityTokenInvalidAudienceException("IDX10215:"), TestId = "ValidAudiencesEmptyString", ValidationParameters = new ValidationParameters{ ValidAudiences = [String.Empty] }, AudienceValidationResult = new AudienceValidationResult( @@ -105,7 +105,7 @@ public static TheoryData ValidateAudienceParameter ValidationFailureType.NullArgument, new ExceptionDetail( new MessageDetail( - LogMessages.IDX10214, + LogMessages.IDX10215, LogHelper.MarkAsNonPII("audience1"), LogHelper.MarkAsNonPII(String.Empty)), typeof(SecurityTokenInvalidAudienceException), @@ -115,7 +115,7 @@ public static TheoryData ValidateAudienceParameter new AudienceValidationTheoryData { Audiences = new List { "audience1" }, - ExpectedException = ExpectedException.SecurityTokenInvalidAudienceException("IDX10214:"), + ExpectedException = ExpectedException.SecurityTokenInvalidAudienceException("IDX10215:"), TestId = "ValidAudiencesWhiteSpace", ValidationParameters = new ValidationParameters{ ValidAudiences = [" "] }, AudienceValidationResult = new AudienceValidationResult( @@ -123,7 +123,7 @@ public static TheoryData ValidateAudienceParameter ValidationFailureType.NullArgument, new ExceptionDetail( new MessageDetail( - LogMessages.IDX10214, + LogMessages.IDX10215, LogHelper.MarkAsNonPII("audience1"), LogHelper.MarkAsNonPII(" ")), typeof(SecurityTokenInvalidAudienceException), @@ -189,7 +189,7 @@ public static TheoryData ValidateAudienceTheoryDat new AudienceValidationTheoryData { Audiences = audiences1, - ExpectedException = ExpectedException.SecurityTokenInvalidAudienceException("IDX10214:"), + ExpectedException = ExpectedException.SecurityTokenInvalidAudienceException("IDX10215:"), TestId = "SameLengthNotMatched", ValidationParameters = new ValidationParameters{ ValidAudiences = [audience2] }, SecurityToken = JsonUtilities.CreateUnsignedJsonWebToken(JwtRegisteredClaimNames.Iss, "Issuer"), @@ -198,7 +198,7 @@ public static TheoryData ValidateAudienceTheoryDat ValidationFailureType.NullArgument, new ExceptionDetail( new MessageDetail( - LogMessages.IDX10214, + LogMessages.IDX10215, LogHelper.MarkAsNonPII(commaAudience1), LogHelper.MarkAsNonPII(audience2)), typeof(SecurityTokenInvalidAudienceException), @@ -208,7 +208,7 @@ public static TheoryData ValidateAudienceTheoryDat new AudienceValidationTheoryData { Audiences = audiences1, - ExpectedException = ExpectedException.SecurityTokenInvalidAudienceException("IDX10214:"), + ExpectedException = ExpectedException.SecurityTokenInvalidAudienceException("IDX10215:"), TestId = "AudiencesValidAudienceWithSlashNotMatched", ValidationParameters = new ValidationParameters{ ValidAudiences = [audience2 + "/"] }, SecurityToken = JsonUtilities.CreateUnsignedJsonWebToken(JwtRegisteredClaimNames.Iss, "Issuer"), @@ -217,7 +217,7 @@ public static TheoryData ValidateAudienceTheoryDat ValidationFailureType.NullArgument, new ExceptionDetail( new MessageDetail( - LogMessages.IDX10214, + LogMessages.IDX10215, LogHelper.MarkAsNonPII(commaAudience1), LogHelper.MarkAsNonPII(audience2Slash)), typeof(SecurityTokenInvalidAudienceException), @@ -227,7 +227,7 @@ public static TheoryData ValidateAudienceTheoryDat new AudienceValidationTheoryData { Audiences = audiences2WithSlash, - ExpectedException = ExpectedException.SecurityTokenInvalidAudienceException("IDX10214:"), + ExpectedException = ExpectedException.SecurityTokenInvalidAudienceException("IDX10215:"), TestId = "AudiencesWithSlashValidAudienceSameLengthNotMatched", ValidationParameters = new ValidationParameters{ ValidAudiences = [audience1] }, AudienceValidationResult = new AudienceValidationResult( @@ -235,7 +235,7 @@ public static TheoryData ValidateAudienceTheoryDat ValidationFailureType.NullArgument, new ExceptionDetail( new MessageDetail( - LogMessages.IDX10214, + LogMessages.IDX10215, LogHelper.MarkAsNonPII(commaAudience2Slash), LogHelper.MarkAsNonPII(audience1)), typeof(SecurityTokenInvalidAudienceException), @@ -245,7 +245,7 @@ public static TheoryData ValidateAudienceTheoryDat new AudienceValidationTheoryData { Audiences = audiences1, - ExpectedException = ExpectedException.SecurityTokenInvalidAudienceException("IDX10214:"), + ExpectedException = ExpectedException.SecurityTokenInvalidAudienceException("IDX10215:"), TestId = "ValidAudienceWithSlashVPFalse", ValidationParameters = new ValidationParameters{ IgnoreTrailingSlashWhenValidatingAudience = false, ValidAudiences = [audience1 + "/"] }, AudienceValidationResult = new AudienceValidationResult( @@ -253,7 +253,7 @@ public static TheoryData ValidateAudienceTheoryDat ValidationFailureType.NullArgument, new ExceptionDetail( new MessageDetail( - LogMessages.IDX10214, + LogMessages.IDX10215, LogHelper.MarkAsNonPII(commaAudience1), LogHelper.MarkAsNonPII(audience1Slash)), typeof(SecurityTokenInvalidAudienceException), @@ -270,7 +270,7 @@ public static TheoryData ValidateAudienceTheoryDat new AudienceValidationTheoryData { Audiences = audiences1, - ExpectedException = ExpectedException.SecurityTokenInvalidAudienceException("IDX10214:"), + ExpectedException = ExpectedException.SecurityTokenInvalidAudienceException("IDX10215:"), TestId = "ValidAudiencesWithSlashVPFalse", ValidationParameters = new ValidationParameters{ IgnoreTrailingSlashWhenValidatingAudience = false, ValidAudiences = audiences1WithSlash }, AudienceValidationResult = new AudienceValidationResult( @@ -278,7 +278,7 @@ public static TheoryData ValidateAudienceTheoryDat ValidationFailureType.NullArgument, new ExceptionDetail( new MessageDetail( - LogMessages.IDX10214, + LogMessages.IDX10215, LogHelper.MarkAsNonPII(commaAudience1), LogHelper.MarkAsNonPII(commaAudience1Slash)), typeof(SecurityTokenInvalidAudienceException), @@ -295,7 +295,7 @@ public static TheoryData ValidateAudienceTheoryDat new AudienceValidationTheoryData { Audiences = audiences1, - ExpectedException = ExpectedException.SecurityTokenInvalidAudienceException("IDX10214:"), + ExpectedException = ExpectedException.SecurityTokenInvalidAudienceException("IDX10215:"), TestId = "ValidAudienceWithExtraChar", ValidationParameters = new ValidationParameters{ ValidAudiences = [audience1 + "A"] }, AudienceValidationResult = new AudienceValidationResult( @@ -303,7 +303,7 @@ public static TheoryData ValidateAudienceTheoryDat ValidationFailureType.NullArgument, new ExceptionDetail( new MessageDetail( - LogMessages.IDX10214, + LogMessages.IDX10215, LogHelper.MarkAsNonPII(commaAudience1), LogHelper.MarkAsNonPII(audience1 + "A")), typeof(SecurityTokenInvalidAudienceException), @@ -313,7 +313,7 @@ public static TheoryData ValidateAudienceTheoryDat new AudienceValidationTheoryData { Audiences = audiences1, - ExpectedException = ExpectedException.SecurityTokenInvalidAudienceException("IDX10214:"), + ExpectedException = ExpectedException.SecurityTokenInvalidAudienceException("IDX10215:"), TestId = "ValidAudienceWithDoubleSlashVPTrue", ValidationParameters = new ValidationParameters{ ValidAudiences = [audience1 + "//"] }, AudienceValidationResult = new AudienceValidationResult( @@ -321,7 +321,7 @@ public static TheoryData ValidateAudienceTheoryDat ValidationFailureType.NullArgument, new ExceptionDetail( new MessageDetail( - LogMessages.IDX10214, + LogMessages.IDX10215, LogHelper.MarkAsNonPII(commaAudience1), LogHelper.MarkAsNonPII(audience1 + "//")), typeof(SecurityTokenInvalidAudienceException), @@ -331,7 +331,7 @@ public static TheoryData ValidateAudienceTheoryDat new AudienceValidationTheoryData { Audiences = audiences1, - ExpectedException = ExpectedException.SecurityTokenInvalidAudienceException("IDX10214:"), + ExpectedException = ExpectedException.SecurityTokenInvalidAudienceException("IDX10215:"), TestId = "ValidAudiencesWithDoubleSlashVPTrue", ValidationParameters = new ValidationParameters{ ValidAudiences = audiences1WithTwoSlashes }, AudienceValidationResult = new AudienceValidationResult( @@ -339,7 +339,7 @@ public static TheoryData ValidateAudienceTheoryDat ValidationFailureType.NullArgument, new ExceptionDetail( new MessageDetail( - LogMessages.IDX10214, + LogMessages.IDX10215, LogHelper.MarkAsNonPII(commaAudience1), LogHelper.MarkAsNonPII(commaAudience1 + "//")), typeof(SecurityTokenInvalidAudienceException), @@ -349,7 +349,7 @@ public static TheoryData ValidateAudienceTheoryDat new AudienceValidationTheoryData { Audiences = audiences1WithSlash, - ExpectedException = ExpectedException.SecurityTokenInvalidAudienceException("IDX10214:"), + ExpectedException = ExpectedException.SecurityTokenInvalidAudienceException("IDX10215:"), TestId = "TokenAudienceWithSlashVPFalse", ValidationParameters = new ValidationParameters{ IgnoreTrailingSlashWhenValidatingAudience = false, ValidAudiences = [audience1] }, AudienceValidationResult = new AudienceValidationResult( @@ -357,7 +357,7 @@ public static TheoryData ValidateAudienceTheoryDat ValidationFailureType.NullArgument, new ExceptionDetail( new MessageDetail( - LogMessages.IDX10214, + LogMessages.IDX10215, LogHelper.MarkAsNonPII(commaAudience1Slash), LogHelper.MarkAsNonPII(audience1)), typeof(SecurityTokenInvalidAudienceException), @@ -374,7 +374,7 @@ public static TheoryData ValidateAudienceTheoryDat new AudienceValidationTheoryData { Audiences = audiences2WithSlash, - ExpectedException = ExpectedException.SecurityTokenInvalidAudienceException("IDX10214:"), + ExpectedException = ExpectedException.SecurityTokenInvalidAudienceException("IDX10215:"), TestId = "TokenAudienceWithSlashNotEqual", ValidationParameters = new ValidationParameters{ ValidAudiences = [audience1] }, AudienceValidationResult = new AudienceValidationResult( @@ -382,7 +382,7 @@ public static TheoryData ValidateAudienceTheoryDat ValidationFailureType.NullArgument, new ExceptionDetail( new MessageDetail( - LogMessages.IDX10214, + LogMessages.IDX10215, LogHelper.MarkAsNonPII(commaAudience2Slash), LogHelper.MarkAsNonPII(audience1)), typeof(SecurityTokenInvalidAudienceException), @@ -392,7 +392,7 @@ public static TheoryData ValidateAudienceTheoryDat new AudienceValidationTheoryData { Audiences = audiences1WithSlash, - ExpectedException = ExpectedException.SecurityTokenInvalidAudienceException("IDX10214:"), + ExpectedException = ExpectedException.SecurityTokenInvalidAudienceException("IDX10215:"), TestId = "TokenAudiencesWithSlashVPFalse", ValidationParameters = new ValidationParameters{ IgnoreTrailingSlashWhenValidatingAudience = false, ValidAudiences = [audience1] }, AudienceValidationResult = new AudienceValidationResult( @@ -400,7 +400,7 @@ public static TheoryData ValidateAudienceTheoryDat ValidationFailureType.NullArgument, new ExceptionDetail( new MessageDetail( - LogMessages.IDX10214, + LogMessages.IDX10215, LogHelper.MarkAsNonPII(commaAudience1Slash), LogHelper.MarkAsNonPII(audience1)), typeof(SecurityTokenInvalidAudienceException), @@ -417,7 +417,7 @@ public static TheoryData ValidateAudienceTheoryDat new AudienceValidationTheoryData { Audiences = audiences1WithSlash, - ExpectedException = ExpectedException.SecurityTokenInvalidAudienceException("IDX10214:"), + ExpectedException = ExpectedException.SecurityTokenInvalidAudienceException("IDX10215:"), TestId = "TokenAudiencesWithSlashValidAudiencesNotMatchedVPTrue", ValidationParameters = new ValidationParameters{ ValidAudiences = audiences2 }, AudienceValidationResult = new AudienceValidationResult( @@ -425,7 +425,7 @@ public static TheoryData ValidateAudienceTheoryDat ValidationFailureType.NullArgument, new ExceptionDetail( new MessageDetail( - LogMessages.IDX10214, + LogMessages.IDX10215, LogHelper.MarkAsNonPII(commaAudience1Slash), LogHelper.MarkAsNonPII(commaAudience2)), typeof(SecurityTokenInvalidAudienceException), @@ -435,7 +435,7 @@ public static TheoryData ValidateAudienceTheoryDat new AudienceValidationTheoryData { Audiences = audiences1WithTwoSlashes, - ExpectedException = ExpectedException.SecurityTokenInvalidAudienceException("IDX10214:"), + ExpectedException = ExpectedException.SecurityTokenInvalidAudienceException("IDX10215:"), TestId = "TokenAudienceWithTwoSlashesVPTrue", ValidationParameters = new ValidationParameters{ ValidAudiences = [audience1] }, AudienceValidationResult = new AudienceValidationResult( @@ -443,7 +443,7 @@ public static TheoryData ValidateAudienceTheoryDat ValidationFailureType.NullArgument, new ExceptionDetail( new MessageDetail( - LogMessages.IDX10214, + LogMessages.IDX10215, LogHelper.MarkAsNonPII(commaAudience1 + "//"), LogHelper.MarkAsNonPII(audience1)), typeof(SecurityTokenInvalidAudienceException), From 0cc32fcd3d45d826980c212690abce03257be978 Mon Sep 17 00:00:00 2001 From: Franco Fung <38921563+FuPingFranco@users.noreply.github.com> Date: Tue, 6 Aug 2024 08:02:38 -0700 Subject: [PATCH 3/3] Address PR feedback. (#2765) * Addressed PR feedback. Updated tests * Removed exception from documentation * Updated TokenType tests --------- Co-authored-by: Ignacio Inglese --- .../Validation/ValidationParameters.cs | 28 +++---- .../Validation/Validators.Audience.cs | 47 +++++------- .../AudienceValidationResultTests.cs | 74 ++++++++++++++----- .../TokenTypeValidationResultTests.cs | 33 ++++----- .../Validation/ValidationParametersTests.cs | 44 ++--------- 5 files changed, 106 insertions(+), 120 deletions(-) diff --git a/src/Microsoft.IdentityModel.Tokens/Validation/ValidationParameters.cs b/src/Microsoft.IdentityModel.Tokens/Validation/ValidationParameters.cs index 5526cd1b7f..d05f6b035c 100644 --- a/src/Microsoft.IdentityModel.Tokens/Validation/ValidationParameters.cs +++ b/src/Microsoft.IdentityModel.Tokens/Validation/ValidationParameters.cs @@ -21,8 +21,8 @@ internal class ValidationParameters private string _nameClaimType = ClaimsIdentity.DefaultNameClaimType; private string _roleClaimType = ClaimsIdentity.DefaultRoleClaimType; private Dictionary _instancePropertyBag; - private IList _validTokenTypes = []; - private IList _validAudiences = []; + private IList _validTokenTypes; + private IList _validAudiences; private AlgorithmValidatorDelegate _algorithmValidator = Validators.ValidateAlgorithm; private AudienceValidatorDelegate _audienceValidator = Validators.ValidateAudience; @@ -90,9 +90,9 @@ protected ValidationParameters(ValidationParameters other) ValidateSignatureLast = other.ValidateSignatureLast; ValidateWithLKG = other.ValidateWithLKG; ValidAlgorithms = other.ValidAlgorithms; - ValidAudiences = other.ValidAudiences; + _validAudiences = other.ValidAudiences; ValidIssuers = other.ValidIssuers; - ValidTypes = other.ValidTypes; + _validTokenTypes = other.ValidTypes; } /// @@ -516,12 +516,10 @@ public TypeValidatorDelegate TypeValidator /// Gets the that contains valid audiences that will be used to check against the token's audience. /// The default is an empty collection. /// - /// Thrown when the value is set as null. - public IList ValidAudiences - { - get { return _validAudiences; } - set { _validAudiences = value ?? throw new ArgumentNullException(nameof(value), "ValidAudiences cannot be set as null."); } - } + public IList ValidAudiences => + _validAudiences ?? + Interlocked.CompareExchange(ref _validAudiences, [], null) ?? + _validAudiences; /// /// Gets the that contains valid issuers that will be used to check against the token's issuer. @@ -535,13 +533,11 @@ public IList ValidAudiences /// In the case of a JWE, this property will ONLY apply to the inner token header. /// The default is an empty collection. /// - /// Thrown when the value is set as null. /// The that contains valid token types that will be used to check against the token's 'typ' claim. - public IList ValidTypes - { - get { return _validTokenTypes; } - set { _validTokenTypes = value ?? throw new ArgumentNullException(nameof(value), "ValidTypes cannot be set as null."); } - } + public IList ValidTypes => + _validTokenTypes ?? + Interlocked.CompareExchange(ref _validTokenTypes, [], null) ?? + _validTokenTypes; public bool ValidateActor { get; set; } } diff --git a/src/Microsoft.IdentityModel.Tokens/Validation/Validators.Audience.cs b/src/Microsoft.IdentityModel.Tokens/Validation/Validators.Audience.cs index 5f5911dba5..337a1e7393 100644 --- a/src/Microsoft.IdentityModel.Tokens/Validation/Validators.Audience.cs +++ b/src/Microsoft.IdentityModel.Tokens/Validation/Validators.Audience.cs @@ -34,7 +34,7 @@ public static partial class Validators /// /// Determines if the audiences found in a are valid. /// - /// The audiences found in the . + /// The audiences found in the . /// The being validated. /// The to be used for validating the token. /// @@ -44,12 +44,12 @@ public static partial class Validators /// If none of the 'audiences' matched either or one of . /// An EXACT match is required. #pragma warning disable CA1801 // TODO: remove pragma disable once callContext is used for logging - internal static AudienceValidationResult ValidateAudience(IList audiences, SecurityToken? securityToken, ValidationParameters validationParameters, CallContext callContext) + internal static AudienceValidationResult ValidateAudience(IList tokenAudiences, SecurityToken? securityToken, ValidationParameters validationParameters, CallContext callContext) #pragma warning restore CA1801 { if (validationParameters == null) return new AudienceValidationResult( - Utility.SerializeAsSingleCommaDelimitedString(audiences), + Utility.SerializeAsSingleCommaDelimitedString(tokenAudiences), ValidationFailureType.NullArgument, new ExceptionDetail( new MessageDetail( @@ -58,9 +58,9 @@ internal static AudienceValidationResult ValidateAudience(IList audience typeof(ArgumentNullException), new StackFrame(true))); - if (audiences == null) + if (tokenAudiences == null) return new AudienceValidationResult( - Utility.SerializeAsSingleCommaDelimitedString(audiences), + Utility.SerializeAsSingleCommaDelimitedString(tokenAudiences), ValidationFailureType.NullArgument, new ExceptionDetail( new MessageDetail( @@ -69,9 +69,9 @@ internal static AudienceValidationResult ValidateAudience(IList audience typeof(SecurityTokenInvalidAudienceException), new StackFrame(true))); - if (audiences.Count == 0) + if (tokenAudiences.Count == 0) return new AudienceValidationResult( - Utility.SerializeAsSingleCommaDelimitedString(audiences), + Utility.SerializeAsSingleCommaDelimitedString(tokenAudiences), ValidationFailureType.NullArgument, new ExceptionDetail( new MessageDetail( @@ -80,39 +80,27 @@ internal static AudienceValidationResult ValidateAudience(IList audience typeof(SecurityTokenInvalidAudienceException), new StackFrame(true))); - string? validAudience = AudienceIsValidReturning((List)audiences, validationParameters); + string? validAudience = ValidTokenAudience(tokenAudiences, validationParameters.ValidAudiences, validationParameters.IgnoreTrailingSlashWhenValidatingAudience); if (validAudience != null) - { return new AudienceValidationResult(validAudience); - } return new AudienceValidationResult( - Utility.SerializeAsSingleCommaDelimitedString(audiences), + Utility.SerializeAsSingleCommaDelimitedString(tokenAudiences), ValidationFailureType.AudienceValidationFailed, new ExceptionDetail( new MessageDetail( LogMessages.IDX10215, - LogHelper.MarkAsNonPII(Utility.SerializeAsSingleCommaDelimitedString(audiences)), + LogHelper.MarkAsNonPII(Utility.SerializeAsSingleCommaDelimitedString(tokenAudiences)), LogHelper.MarkAsNonPII(Utility.SerializeAsSingleCommaDelimitedString(validationParameters.ValidAudiences))), typeof(SecurityTokenInvalidAudienceException), new StackFrame(true))); } - private static string? AudienceIsValidReturning(List audiences, ValidationParameters validationParameters) - { - string? validAudience = null; - - List validAudiences = [.. validationParameters.ValidAudiences]; - validAudience = AudiencesMatchList(audiences, validAudiences, validationParameters.IgnoreTrailingSlashWhenValidatingAudience); - - return validAudience; - } - - private static string? AudiencesMatchList(IList audiences, List validAudiences, bool ignoreTrailingSlashWhenValidatingAudience) + private static string? ValidTokenAudience(IList tokenAudiences, IList validAudiences, bool ignoreTrailingSlashWhenValidatingAudience) { - for (int i = 0; i < audiences.Count; i++) + for (int i = 0; i < tokenAudiences.Count; i++) { - string tokenAudience = audiences[i]; + string tokenAudience = tokenAudiences[i]; if (string.IsNullOrEmpty(tokenAudience)) continue; @@ -121,7 +109,8 @@ internal static AudienceValidationResult ValidateAudience(IList audience if (string.IsNullOrEmpty(validAudiences[j])) continue; - if (AudiencesMatch(ignoreTrailingSlashWhenValidatingAudience, tokenAudience, validAudiences[j])) + + if (AudienceMatches(ignoreTrailingSlashWhenValidatingAudience, tokenAudience, validAudiences[j])) { if (LogHelper.IsEnabled(EventLogLevel.Informational)) LogHelper.LogInformation(LogMessages.IDX10234, LogHelper.MarkAsNonPII(tokenAudience)); @@ -134,17 +123,17 @@ internal static AudienceValidationResult ValidateAudience(IList audience return null; } - private static bool AudiencesMatch(bool ignoreTrailingSlashWhenValidatingAudience, string tokenAudience, string validAudience) + private static bool AudienceMatches(bool ignoreTrailingSlashWhenValidatingAudience, string tokenAudience, string validAudience) { if (validAudience.Length == tokenAudience.Length) return string.Equals(validAudience, tokenAudience); - else if (ignoreTrailingSlashWhenValidatingAudience && NewAudiencesMatchIgnoringTrailingSlash(tokenAudience, validAudience)) + else if (ignoreTrailingSlashWhenValidatingAudience && AudienceMatchesIgnoringTrailingSlash(tokenAudience, validAudience)) return true; return false; } - private static bool NewAudiencesMatchIgnoringTrailingSlash(string tokenAudience, string validAudience) + private static bool AudienceMatchesIgnoringTrailingSlash(string tokenAudience, string validAudience) { int length = -1; diff --git a/test/Microsoft.IdentityModel.Tokens.Tests/Validation/AudienceValidationResultTests.cs b/test/Microsoft.IdentityModel.Tokens.Tests/Validation/AudienceValidationResultTests.cs index 578a638893..4c4a732613 100644 --- a/test/Microsoft.IdentityModel.Tokens.Tests/Validation/AudienceValidationResultTests.cs +++ b/test/Microsoft.IdentityModel.Tokens.Tests/Validation/AudienceValidationResultTests.cs @@ -19,6 +19,12 @@ public void ValidateAudienceParameters(AudienceValidationTheoryData theoryData) { CompareContext context = TestUtilities.WriteHeader($"{this}.AudienceValidatorResultTests", theoryData); + if (theoryData.AudiencesToAdd != null) + { + foreach (string audience in theoryData.AudiencesToAdd) + theoryData.ValidationParameters.ValidAudiences.Add(audience); + } + AudienceValidationResult audienceValidationResult = Validators.ValidateAudience( theoryData.Audiences, theoryData.SecurityToken, @@ -99,7 +105,8 @@ public static TheoryData ValidateAudienceParameter Audiences = new List { "audience1" }, ExpectedException = ExpectedException.SecurityTokenInvalidAudienceException("IDX10215:"), TestId = "ValidAudiencesEmptyString", - ValidationParameters = new ValidationParameters{ ValidAudiences = [String.Empty] }, + ValidationParameters = new ValidationParameters(), + AudiencesToAdd = [String.Empty], AudienceValidationResult = new AudienceValidationResult( "audience1", ValidationFailureType.NullArgument, @@ -117,7 +124,8 @@ public static TheoryData ValidateAudienceParameter Audiences = new List { "audience1" }, ExpectedException = ExpectedException.SecurityTokenInvalidAudienceException("IDX10215:"), TestId = "ValidAudiencesWhiteSpace", - ValidationParameters = new ValidationParameters{ ValidAudiences = [" "] }, + ValidationParameters = new ValidationParameters(), + AudiencesToAdd = [" "], AudienceValidationResult = new AudienceValidationResult( "audience1", ValidationFailureType.NullArgument, @@ -138,6 +146,13 @@ public static TheoryData ValidateAudienceParameter public void ValidateAudience(AudienceValidationTheoryData theoryData) { var context = TestUtilities.WriteHeader($"{this}.ValidateAudience", theoryData); + + if (theoryData.AudiencesToAdd != null) + { + foreach (string audience in theoryData.AudiencesToAdd) + theoryData.ValidationParameters.ValidAudiences.Add(audience); + } + AudienceValidationResult audienceValidationResult = Validators.ValidateAudience( theoryData.Audiences, theoryData.SecurityToken, @@ -182,7 +197,8 @@ public static TheoryData ValidateAudienceTheoryDat { Audiences = audiences1, TestId = "SameLengthMatched", - ValidationParameters = new ValidationParameters{ ValidAudiences = [audience1] }, + ValidationParameters = new ValidationParameters(), + AudiencesToAdd = [audience1], SecurityToken = JsonUtilities.CreateUnsignedJsonWebToken(JwtRegisteredClaimNames.Iss, "Issuer"), AudienceValidationResult = new AudienceValidationResult(audience1) }, @@ -191,7 +207,8 @@ public static TheoryData ValidateAudienceTheoryDat Audiences = audiences1, ExpectedException = ExpectedException.SecurityTokenInvalidAudienceException("IDX10215:"), TestId = "SameLengthNotMatched", - ValidationParameters = new ValidationParameters{ ValidAudiences = [audience2] }, + ValidationParameters = new ValidationParameters(), + AudiencesToAdd = [audience2], SecurityToken = JsonUtilities.CreateUnsignedJsonWebToken(JwtRegisteredClaimNames.Iss, "Issuer"), AudienceValidationResult = new AudienceValidationResult( commaAudience1, @@ -210,7 +227,8 @@ public static TheoryData ValidateAudienceTheoryDat Audiences = audiences1, ExpectedException = ExpectedException.SecurityTokenInvalidAudienceException("IDX10215:"), TestId = "AudiencesValidAudienceWithSlashNotMatched", - ValidationParameters = new ValidationParameters{ ValidAudiences = [audience2 + "/"] }, + ValidationParameters = new ValidationParameters(), + AudiencesToAdd = [audience2 + "/"], SecurityToken = JsonUtilities.CreateUnsignedJsonWebToken(JwtRegisteredClaimNames.Iss, "Issuer"), AudienceValidationResult = new AudienceValidationResult( commaAudience1, @@ -229,7 +247,8 @@ public static TheoryData ValidateAudienceTheoryDat Audiences = audiences2WithSlash, ExpectedException = ExpectedException.SecurityTokenInvalidAudienceException("IDX10215:"), TestId = "AudiencesWithSlashValidAudienceSameLengthNotMatched", - ValidationParameters = new ValidationParameters{ ValidAudiences = [audience1] }, + ValidationParameters = new ValidationParameters(), + AudiencesToAdd = [audience1], AudienceValidationResult = new AudienceValidationResult( commaAudience2Slash, ValidationFailureType.NullArgument, @@ -247,7 +266,8 @@ public static TheoryData ValidateAudienceTheoryDat Audiences = audiences1, ExpectedException = ExpectedException.SecurityTokenInvalidAudienceException("IDX10215:"), TestId = "ValidAudienceWithSlashVPFalse", - ValidationParameters = new ValidationParameters{ IgnoreTrailingSlashWhenValidatingAudience = false, ValidAudiences = [audience1 + "/"] }, + ValidationParameters = new ValidationParameters{ IgnoreTrailingSlashWhenValidatingAudience = false }, + AudiencesToAdd = [audience1 + "/"], AudienceValidationResult = new AudienceValidationResult( commaAudience1, ValidationFailureType.NullArgument, @@ -264,7 +284,8 @@ public static TheoryData ValidateAudienceTheoryDat { Audiences = audiences1, TestId = "ValidAudienceWithSlashVPTrue", - ValidationParameters = new ValidationParameters{ ValidAudiences = [audience1 + "/"] }, + ValidationParameters = new ValidationParameters(), + AudiencesToAdd = [audience1 + "/"], AudienceValidationResult = new AudienceValidationResult(audience1) }, new AudienceValidationTheoryData @@ -272,7 +293,8 @@ public static TheoryData ValidateAudienceTheoryDat Audiences = audiences1, ExpectedException = ExpectedException.SecurityTokenInvalidAudienceException("IDX10215:"), TestId = "ValidAudiencesWithSlashVPFalse", - ValidationParameters = new ValidationParameters{ IgnoreTrailingSlashWhenValidatingAudience = false, ValidAudiences = audiences1WithSlash }, + ValidationParameters = new ValidationParameters{ IgnoreTrailingSlashWhenValidatingAudience = false }, + AudiencesToAdd = audiences1WithSlash, AudienceValidationResult = new AudienceValidationResult( commaAudience1, ValidationFailureType.NullArgument, @@ -289,7 +311,8 @@ public static TheoryData ValidateAudienceTheoryDat { Audiences = audiences1, TestId = "ValidAudiencesWithSlashVPTrue", - ValidationParameters = new ValidationParameters{ ValidAudiences = audiences1WithSlash }, + ValidationParameters = new ValidationParameters(), + AudiencesToAdd = audiences1WithSlash, AudienceValidationResult = new AudienceValidationResult(audience1) }, new AudienceValidationTheoryData @@ -297,7 +320,8 @@ public static TheoryData ValidateAudienceTheoryDat Audiences = audiences1, ExpectedException = ExpectedException.SecurityTokenInvalidAudienceException("IDX10215:"), TestId = "ValidAudienceWithExtraChar", - ValidationParameters = new ValidationParameters{ ValidAudiences = [audience1 + "A"] }, + ValidationParameters = new ValidationParameters(), + AudiencesToAdd = [audience1 + "A"], AudienceValidationResult = new AudienceValidationResult( commaAudience1, ValidationFailureType.NullArgument, @@ -315,7 +339,8 @@ public static TheoryData ValidateAudienceTheoryDat Audiences = audiences1, ExpectedException = ExpectedException.SecurityTokenInvalidAudienceException("IDX10215:"), TestId = "ValidAudienceWithDoubleSlashVPTrue", - ValidationParameters = new ValidationParameters{ ValidAudiences = [audience1 + "//"] }, + ValidationParameters = new ValidationParameters(), + AudiencesToAdd = [audience1 + "//"], AudienceValidationResult = new AudienceValidationResult( commaAudience1, ValidationFailureType.NullArgument, @@ -333,7 +358,8 @@ public static TheoryData ValidateAudienceTheoryDat Audiences = audiences1, ExpectedException = ExpectedException.SecurityTokenInvalidAudienceException("IDX10215:"), TestId = "ValidAudiencesWithDoubleSlashVPTrue", - ValidationParameters = new ValidationParameters{ ValidAudiences = audiences1WithTwoSlashes }, + ValidationParameters = new ValidationParameters(), + AudiencesToAdd = audiences1WithTwoSlashes, AudienceValidationResult = new AudienceValidationResult( commaAudience1, ValidationFailureType.NullArgument, @@ -351,7 +377,8 @@ public static TheoryData ValidateAudienceTheoryDat Audiences = audiences1WithSlash, ExpectedException = ExpectedException.SecurityTokenInvalidAudienceException("IDX10215:"), TestId = "TokenAudienceWithSlashVPFalse", - ValidationParameters = new ValidationParameters{ IgnoreTrailingSlashWhenValidatingAudience = false, ValidAudiences = [audience1] }, + ValidationParameters = new ValidationParameters{ IgnoreTrailingSlashWhenValidatingAudience = false }, + AudiencesToAdd = [audience1], AudienceValidationResult = new AudienceValidationResult( commaAudience1Slash, ValidationFailureType.NullArgument, @@ -368,7 +395,8 @@ public static TheoryData ValidateAudienceTheoryDat { Audiences = audiences1WithSlash, TestId = "TokenAudienceWithSlashVPTrue", - ValidationParameters = new ValidationParameters{ ValidAudiences = [audience1] }, + ValidationParameters = new ValidationParameters(), + AudiencesToAdd = [audience1], AudienceValidationResult = new AudienceValidationResult(audience1Slash) }, new AudienceValidationTheoryData @@ -376,7 +404,8 @@ public static TheoryData ValidateAudienceTheoryDat Audiences = audiences2WithSlash, ExpectedException = ExpectedException.SecurityTokenInvalidAudienceException("IDX10215:"), TestId = "TokenAudienceWithSlashNotEqual", - ValidationParameters = new ValidationParameters{ ValidAudiences = [audience1] }, + ValidationParameters = new ValidationParameters(), + AudiencesToAdd = [audience1], AudienceValidationResult = new AudienceValidationResult( commaAudience2Slash, ValidationFailureType.NullArgument, @@ -394,7 +423,8 @@ public static TheoryData ValidateAudienceTheoryDat Audiences = audiences1WithSlash, ExpectedException = ExpectedException.SecurityTokenInvalidAudienceException("IDX10215:"), TestId = "TokenAudiencesWithSlashVPFalse", - ValidationParameters = new ValidationParameters{ IgnoreTrailingSlashWhenValidatingAudience = false, ValidAudiences = [audience1] }, + ValidationParameters = new ValidationParameters{ IgnoreTrailingSlashWhenValidatingAudience = false }, + AudiencesToAdd = [audience1], AudienceValidationResult = new AudienceValidationResult( commaAudience1Slash, ValidationFailureType.NullArgument, @@ -411,7 +441,8 @@ public static TheoryData ValidateAudienceTheoryDat { Audiences = audiences1WithSlash, TestId = "TokenAudiencesWithSlashVPTrue", - ValidationParameters = new ValidationParameters{ ValidAudiences = [audience1] }, + ValidationParameters = new ValidationParameters(), + AudiencesToAdd = [audience1], AudienceValidationResult = new AudienceValidationResult(audience1Slash) }, new AudienceValidationTheoryData @@ -419,7 +450,8 @@ public static TheoryData ValidateAudienceTheoryDat Audiences = audiences1WithSlash, ExpectedException = ExpectedException.SecurityTokenInvalidAudienceException("IDX10215:"), TestId = "TokenAudiencesWithSlashValidAudiencesNotMatchedVPTrue", - ValidationParameters = new ValidationParameters{ ValidAudiences = audiences2 }, + ValidationParameters = new ValidationParameters(), + AudiencesToAdd = audiences2, AudienceValidationResult = new AudienceValidationResult( commaAudience1Slash, ValidationFailureType.NullArgument, @@ -437,7 +469,8 @@ public static TheoryData ValidateAudienceTheoryDat Audiences = audiences1WithTwoSlashes, ExpectedException = ExpectedException.SecurityTokenInvalidAudienceException("IDX10215:"), TestId = "TokenAudienceWithTwoSlashesVPTrue", - ValidationParameters = new ValidationParameters{ ValidAudiences = [audience1] }, + ValidationParameters = new ValidationParameters(), + AudiencesToAdd = [audience1], AudienceValidationResult = new AudienceValidationResult( commaAudience1 + "//", ValidationFailureType.NullArgument, @@ -465,6 +498,7 @@ public class AudienceValidationTheoryData : TheoryDataBase internal ValidationParameters ValidationParameters { get; set; } = new ValidationParameters(); internal ValidationFailureType ValidationFailureType { get; set; } + public List AudiencesToAdd { get; internal set; } } diff --git a/test/Microsoft.IdentityModel.Tokens.Tests/Validation/TokenTypeValidationResultTests.cs b/test/Microsoft.IdentityModel.Tokens.Tests/Validation/TokenTypeValidationResultTests.cs index 79dd4fce77..f03bc68048 100644 --- a/test/Microsoft.IdentityModel.Tokens.Tests/Validation/TokenTypeValidationResultTests.cs +++ b/test/Microsoft.IdentityModel.Tokens.Tests/Validation/TokenTypeValidationResultTests.cs @@ -8,6 +8,7 @@ using Microsoft.IdentityModel.JsonWebTokens; using Microsoft.IdentityModel.Logging; using Xunit; +using System.Collections.Generic; namespace Microsoft.IdentityModel.Tokens.Validation.Tests { @@ -18,6 +19,12 @@ public void ValidateTokenType(TokenTypeTheoryData theoryData) { CompareContext context = TestUtilities.WriteHeader($"{this}.TokenTypeValidationResultTests", theoryData); + if (theoryData.TokenTypesToAdd != null) + { + foreach (string tokenType in theoryData.TokenTypesToAdd) + theoryData.ValidationParameters.ValidTypes.Add(tokenType); + } + TokenTypeValidationResult tokenTypeValidationResult = Validators.ValidateTokenType( theoryData.Type, theoryData.SecurityToken, @@ -52,10 +59,8 @@ public static TheoryData TokenTypeValidationTestCases TestId = "Valid_DefaultTokenTypeValidation", Type = "JWT", SecurityToken = JsonUtilities.CreateUnsignedJsonWebToken(JwtRegisteredClaimNames.Typ, "JWT"), - ValidationParameters = new ValidationParameters - { - ValidTypes = validTypesWithJwt - }, + ValidationParameters = new ValidationParameters(), + TokenTypesToAdd = validTypesWithJwt, TokenTypeValidationResult = new TokenTypeValidationResult("JWT") }, new TokenTypeTheoryData @@ -98,10 +103,8 @@ public static TheoryData TokenTypeValidationTestCases ExpectedException = ExpectedException.SecurityTokenInvalidTypeException("IDX10256:"), Type = String.Empty, SecurityToken = JsonUtilities.CreateUnsignedJsonWebToken(JwtRegisteredClaimNames.Typ, String.Empty), - ValidationParameters = new ValidationParameters - { - ValidTypes = validTypesNoJwt - }, + ValidationParameters = new ValidationParameters(), + TokenTypesToAdd = validTypesNoJwt, TokenTypeValidationResult = new TokenTypeValidationResult( string.Empty, ValidationFailureType.TokenTypeValidationFailed, @@ -118,10 +121,8 @@ public static TheoryData TokenTypeValidationTestCases ExpectedException = ExpectedException.SecurityTokenInvalidTypeException("IDX10256:"), Type = null, SecurityToken = JsonUtilities.CreateUnsignedJsonWebToken(JwtRegisteredClaimNames.Typ, null), - ValidationParameters = new ValidationParameters - { - ValidTypes = validTypesNoJwt - }, + ValidationParameters = new ValidationParameters(), + TokenTypesToAdd = validTypesNoJwt, TokenTypeValidationResult = new TokenTypeValidationResult( null, ValidationFailureType.TokenTypeValidationFailed, @@ -138,10 +139,8 @@ public static TheoryData TokenTypeValidationTestCases ExpectedException = ExpectedException.SecurityTokenInvalidTypeException("IDX10257:"), Type = "JWT", SecurityToken = JsonUtilities.CreateUnsignedJsonWebToken(JwtRegisteredClaimNames.Typ, "JWT"), - ValidationParameters = new ValidationParameters - { - ValidTypes = validTypesNoJwt - }, + ValidationParameters = new ValidationParameters(), + TokenTypesToAdd = validTypesNoJwt, TokenTypeValidationResult = new TokenTypeValidationResult( "JWT", ValidationFailureType.TokenTypeValidationFailed, @@ -162,7 +161,7 @@ public class TokenTypeTheoryData : TheoryDataBase public string Type { get; set; } public SecurityToken SecurityToken { get; set; } - + public IList TokenTypesToAdd { get; internal set; } internal ValidationParameters ValidationParameters { get; set; } internal TokenTypeValidationResult TokenTypeValidationResult { get; set; } diff --git a/test/Microsoft.IdentityModel.Tokens.Tests/Validation/ValidationParametersTests.cs b/test/Microsoft.IdentityModel.Tokens.Tests/Validation/ValidationParametersTests.cs index 17a3c3fee6..a3cdce765b 100644 --- a/test/Microsoft.IdentityModel.Tokens.Tests/Validation/ValidationParametersTests.cs +++ b/test/Microsoft.IdentityModel.Tokens.Tests/Validation/ValidationParametersTests.cs @@ -21,52 +21,20 @@ public void SetValidators_NullValue_ThrowsArgumentNullException() } [Fact] - public void ValidAudiences_GetSet_ValidValue_Success() + public void ValidAudiences_Get_ReturnsEmptyList() { var validationParameters = new ValidationParameters(); - var validAudiences = new List { "audience1", "audience2" }; - validationParameters.ValidAudiences = validAudiences; - - Assert.Equal(validAudiences, validationParameters.ValidAudiences); - } - - [Fact] - public void ValidAudiences_SetNull_ThrowsArgumentNullException() - { - var validationParameters = new ValidationParameters(); - - Assert.Throws(() => validationParameters.ValidAudiences = null); - } - - [Fact] - public void ValidTypes_Get_ReturnsValidTokenTypes() - { - var validationParameters = new ValidationParameters(); - var validTokenTypes = new List { "JWT", "SAML" }; - validationParameters.ValidTypes = validTokenTypes; - - var result = validationParameters.ValidTypes; - - Assert.Equal(validTokenTypes, result); - } - - [Fact] - public void ValidTypes_Set_UpdatesValidTokenTypes() - { - var validationParameters = new ValidationParameters(); - var validTokenTypes = new List { "JWT", "SAML" }; - - validationParameters.ValidTypes = validTokenTypes; - - Assert.Equal(validTokenTypes, validationParameters.ValidTypes); + Assert.Equal(0, validationParameters.ValidAudiences.Count); + Assert.True(validationParameters.ValidAudiences is IList); } [Fact] - public void ValidTypes_Set_Null_ThrowsArgumentNullException() + public void ValidTypes_Get_ReturnsEmptyList() { var validationParameters = new ValidationParameters(); - Assert.Throws(() => validationParameters.ValidTypes = null); + Assert.Equal(0, validationParameters.ValidTypes.Count); + Assert.True(validationParameters.ValidTypes is IList); } } }