From fc0692fc1e9511775bcce00280803bda4a02f3db Mon Sep 17 00:00:00 2001 From: Franco Fung Date: Wed, 31 Jul 2024 18:46:26 -0700 Subject: [PATCH 1/3] Re-factor issuer validator to follow new validation model --- .../LogMessages.cs | 1 + .../Validation/ValidationParameters.cs | 14 +++-- .../Validation/Validators.Issuer.cs | 39 ++++-------- .../Validation/AsyncValidatorsTests.cs | 4 +- .../Validation/IssuerValidationResultTests.cs | 60 +++++++------------ 5 files changed, 49 insertions(+), 69 deletions(-) diff --git a/src/Microsoft.IdentityModel.Tokens/LogMessages.cs b/src/Microsoft.IdentityModel.Tokens/LogMessages.cs index d7ecd84c59..39e4bb3674 100644 --- a/src/Microsoft.IdentityModel.Tokens/LogMessages.cs +++ b/src/Microsoft.IdentityModel.Tokens/LogMessages.cs @@ -36,6 +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 IDX10212 = "IDX10212: Issuer validation failed. Issuer: '{0}'. Did not match any: validationParameters.ValidIssuers: '{1}' or validationParameters.ConfigurationManager.CurrentConfiguration.Issuer: '{2}'. For more details, see https://aka.ms/IdentityModel/issuer-validation. "; public const string IDX10214 = "IDX10214: Audience validation failed. Audiences: '{0}'. Did not match: validationParameters.ValidAudience: '{1}' or validationParameters.ValidAudiences: '{2}'."; 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}'."; diff --git a/src/Microsoft.IdentityModel.Tokens/Validation/ValidationParameters.cs b/src/Microsoft.IdentityModel.Tokens/Validation/ValidationParameters.cs index c064531798..2c8fbb5d3b 100644 --- a/src/Microsoft.IdentityModel.Tokens/Validation/ValidationParameters.cs +++ b/src/Microsoft.IdentityModel.Tokens/Validation/ValidationParameters.cs @@ -5,7 +5,6 @@ using System.Collections.Generic; using System.ComponentModel; using System.Security.Claims; -using System.Threading; using Microsoft.IdentityModel.Abstractions; using Microsoft.IdentityModel.Logging; @@ -21,6 +20,7 @@ internal class ValidationParameters private string _nameClaimType = ClaimsIdentity.DefaultNameClaimType; private string _roleClaimType = ClaimsIdentity.DefaultRoleClaimType; private Dictionary _instancePropertyBag; + private IList _validIssuers = []; private IList _validTokenTypes = []; private AlgorithmValidatorDelegate _algorithmValidator = Validators.ValidateAlgorithm; @@ -518,10 +518,16 @@ public TypeValidatorDelegate TypeValidator public IList ValidAudiences { get; } /// - /// Gets the that contains valid issuers that will be used to check against the token's issuer. - /// The default is null. + /// Gets or sets the that contains valid issuers that will be used to check against the token's issuer. + /// The default is an empty collection. /// - public IList ValidIssuers { get; } + /// Thrown when the value is set as null. + /// The that contains valid issuers that will be used to check against the token's 'iss' claim. + public IList ValidIssuers + { + get { return _validIssuers; } + set { _validIssuers = value ?? throw new ArgumentNullException(nameof(value), "ValidIssuers cannot be set as null."); } + } /// /// Gets the that contains valid types that will be used to check against the JWT header's 'typ' claim. diff --git a/src/Microsoft.IdentityModel.Tokens/Validation/Validators.Issuer.cs b/src/Microsoft.IdentityModel.Tokens/Validation/Validators.Issuer.cs index d1db65f255..c1cb94a744 100644 --- a/src/Microsoft.IdentityModel.Tokens/Validation/Validators.Issuer.cs +++ b/src/Microsoft.IdentityModel.Tokens/Validation/Validators.Issuer.cs @@ -15,15 +15,15 @@ namespace Microsoft.IdentityModel.Tokens /// /// The issuer to validate. /// The that is being validated. - /// The to be used for validating the token. + /// The to be used for validating the token. /// /// - /// A that contains the results of validating the issuer. + /// An that contains the results of validating the issuer. /// This delegate is not expected to throw. internal delegate Task IssuerValidationDelegateAsync( string issuer, SecurityToken securityToken, - TokenValidationParameters validationParameters, + ValidationParameters validationParameters, CallContext callContext, CancellationToken cancellationToken); @@ -37,19 +37,15 @@ public static partial class Validators /// /// The issuer to validate /// The that is being validated. - /// The to be used for validating the token. + /// The to be used for validating the token. /// /// - /// The issuer to use when creating the "Claim"(s) in a "ClaimsIdentity". - /// If 'validationParameters' is null. - /// If 'issuer' is null or whitespace and is true. - /// If is null or whitespace and is null. - /// If 'issuer' failed to matched either or one of . + /// An that contains the results of validating the issuer. /// An EXACT match is required. internal static async Task ValidateIssuerAsync( string issuer, SecurityToken securityToken, - TokenValidationParameters validationParameters, + ValidationParameters validationParameters, CallContext callContext, CancellationToken cancellationToken) { @@ -95,10 +91,8 @@ internal static async Task ValidateIssuerAsync( if (validationParameters.ConfigurationManager != null) configuration = await validationParameters.ConfigurationManager.GetBaseConfigurationAsync(cancellationToken).ConfigureAwait(false); - // Throw if all possible places to validate against are null or empty - if (string.IsNullOrWhiteSpace(validationParameters.ValidIssuer) - && validationParameters.ValidIssuers.IsNullOrEmpty() - && string.IsNullOrWhiteSpace(configuration?.Issuer)) + // Return failed IssuerValidationResult if all possible places to validate against are null or empty. + if (validationParameters.ValidIssuers.IsNullOrEmpty() && string.IsNullOrWhiteSpace(configuration?.Issuer)) { return new IssuerValidationResult( issuer, @@ -126,17 +120,11 @@ internal static async Task ValidateIssuerAsync( } } - if (string.Equals(validationParameters.ValidIssuer, issuer)) + if (validationParameters.ValidIssuers.Count != 0) { - return new IssuerValidationResult(issuer, - IssuerValidationResult.ValidationSource.IssuerIsValidIssuer); - } - - if (validationParameters.ValidIssuers != null) - { - foreach (string str in validationParameters.ValidIssuers) + for (int i = 0; i < validationParameters.ValidIssuers.Count; i++) { - if (string.IsNullOrEmpty(str)) + if (string.IsNullOrEmpty(validationParameters.ValidIssuers[i])) { if (LogHelper.IsEnabled(EventLogLevel.Informational)) LogHelper.LogInformation(LogMessages.IDX10262); @@ -144,7 +132,7 @@ internal static async Task ValidateIssuerAsync( continue; } - if (string.Equals(str, issuer)) + if (string.Equals(validationParameters.ValidIssuers[i], issuer)) { if (LogHelper.IsEnabled(EventLogLevel.Informational)) LogHelper.LogInformation(LogMessages.IDX10236, LogHelper.MarkAsNonPII(issuer)); @@ -160,9 +148,8 @@ internal static async Task ValidateIssuerAsync( ValidationFailureType.IssuerValidationFailed, new ExceptionDetail( new MessageDetail( - LogMessages.IDX10205, + LogMessages.IDX10212, LogHelper.MarkAsNonPII(issuer), - LogHelper.MarkAsNonPII(validationParameters.ValidIssuer ?? "null"), LogHelper.MarkAsNonPII(Utility.SerializeAsSingleCommaDelimitedString(validationParameters.ValidIssuers)), LogHelper.MarkAsNonPII(configuration?.Issuer)), typeof(SecurityTokenInvalidIssuerException), diff --git a/test/Microsoft.IdentityModel.Tokens.Tests/Validation/AsyncValidatorsTests.cs b/test/Microsoft.IdentityModel.Tokens.Tests/Validation/AsyncValidatorsTests.cs index f5bacfc0b7..d96f7bc596 100644 --- a/test/Microsoft.IdentityModel.Tokens.Tests/Validation/AsyncValidatorsTests.cs +++ b/test/Microsoft.IdentityModel.Tokens.Tests/Validation/AsyncValidatorsTests.cs @@ -41,7 +41,7 @@ public static TheoryData AsyncIssuerValidatorTestCase theoryData.Add(new IssuerValidatorTheoryData { Issuer = null, - ValidationParameters = new TokenValidationParameters(), + ValidationParameters = new ValidationParameters(), }); return theoryData; @@ -52,7 +52,7 @@ public static TheoryData AsyncIssuerValidatorTestCase public class IssuerValidatorTheoryData : TheoryDataBase { public string Issuer { get; set; } - public TokenValidationParameters ValidationParameters { get; set; } + internal ValidationParameters ValidationParameters { get; set; } public SecurityToken SecurityToken { get; set; } } } diff --git a/test/Microsoft.IdentityModel.Tokens.Tests/Validation/IssuerValidationResultTests.cs b/test/Microsoft.IdentityModel.Tokens.Tests/Validation/IssuerValidationResultTests.cs index 51ad101026..b3be4a1a88 100644 --- a/test/Microsoft.IdentityModel.Tokens.Tests/Validation/IssuerValidationResultTests.cs +++ b/test/Microsoft.IdentityModel.Tokens.Tests/Validation/IssuerValidationResultTests.cs @@ -56,26 +56,8 @@ public static TheoryData IssuerValdationResul string validIssuer = Guid.NewGuid().ToString(); string issClaim = Guid.NewGuid().ToString(); - theoryData.Add(new IssuerValidationResultsTheoryData("Invalid_Issuer") - { - ExpectedException = ExpectedException.SecurityTokenInvalidIssuerException("IDX10205:"), - Issuer = issClaim, - IssuerValidationResult = new IssuerValidationResult( - issClaim, - ValidationFailureType.IssuerValidationFailed, - new ExceptionDetail( - new MessageDetail( - LogMessages.IDX10205, - LogHelper.MarkAsNonPII(issClaim), - LogHelper.MarkAsNonPII(validIssuer), - LogHelper.MarkAsNonPII(Utility.SerializeAsSingleCommaDelimitedString(null)), - LogHelper.MarkAsNonPII(null)), - typeof(SecurityTokenInvalidIssuerException), - new StackFrame(true))), - IsValid = false, - SecurityToken = JsonUtilities.CreateUnsignedJsonWebToken(JwtRegisteredClaimNames.Iss, issClaim), - ValidationParameters = new TokenValidationParameters { ValidIssuer = validIssuer } - }); + var validConfig = new OpenIdConnectConfiguration() { Issuer = issClaim }; + string[] validIssuers = new string[] { validIssuer }; theoryData.Add(new IssuerValidationResultsTheoryData("NULL_Issuer") { @@ -94,7 +76,7 @@ public static TheoryData IssuerValdationResul new StackFrame(true))), IsValid = false, SecurityToken = JsonUtilities.CreateUnsignedJsonWebToken(JwtRegisteredClaimNames.Iss, issClaim), - ValidationParameters = new TokenValidationParameters(), + ValidationParameters = new ValidationParameters() }); theoryData.Add(new IssuerValidationResultsTheoryData("NULL_ValidationParameters") @@ -132,10 +114,9 @@ public static TheoryData IssuerValdationResul null)), IsValid = false, SecurityToken = null, - ValidationParameters = new TokenValidationParameters() + ValidationParameters = new ValidationParameters() }); - var validConfig = new OpenIdConnectConfiguration() { Issuer = issClaim }; theoryData.Add(new IssuerValidationResultsTheoryData("Valid_FromConfig") { ExpectedException = ExpectedException.NoExceptionExpected, @@ -145,40 +126,45 @@ public static TheoryData IssuerValdationResul IssuerValidationResult.ValidationSource.IssuerIsConfigurationIssuer), IsValid = true, SecurityToken = JsonUtilities.CreateUnsignedJsonWebToken(JwtRegisteredClaimNames.Iss, issClaim), - ValidationParameters = new TokenValidationParameters() + ValidationParameters = new ValidationParameters() { ConfigurationManager = new MockConfigurationManager(validConfig) } }); - theoryData.Add(new IssuerValidationResultsTheoryData("Valid_FromValidationParametersValidIssuer") + theoryData.Add(new IssuerValidationResultsTheoryData("Valid_FromValidationParametersValidIssuers") { ExpectedException = ExpectedException.NoExceptionExpected, Issuer = issClaim, IssuerValidationResult = new IssuerValidationResult( issClaim, - IssuerValidationResult.ValidationSource.IssuerIsValidIssuer), + IssuerValidationResult.ValidationSource.IssuerIsAmongValidIssuers), IsValid = true, SecurityToken = JsonUtilities.CreateUnsignedJsonWebToken(JwtRegisteredClaimNames.Iss, issClaim), - ValidationParameters = new TokenValidationParameters() + ValidationParameters = new ValidationParameters() { - ValidIssuer = issClaim + ValidIssuers = [issClaim] } }); - theoryData.Add(new IssuerValidationResultsTheoryData("Valid_FromValidationParametersValidIssuers") + theoryData.Add(new IssuerValidationResultsTheoryData("Invalid_Issuer") { - ExpectedException = ExpectedException.NoExceptionExpected, + ExpectedException = ExpectedException.SecurityTokenInvalidIssuerException("IDX10212:"), Issuer = issClaim, IssuerValidationResult = new IssuerValidationResult( issClaim, - IssuerValidationResult.ValidationSource.IssuerIsAmongValidIssuers), - IsValid = true, + ValidationFailureType.IssuerValidationFailed, + new ExceptionDetail( + new MessageDetail( + LogMessages.IDX10212, + LogHelper.MarkAsNonPII(issClaim), + LogHelper.MarkAsNonPII(Utility.SerializeAsSingleCommaDelimitedString(validIssuers)), + LogHelper.MarkAsNonPII(null)), + typeof(SecurityTokenInvalidIssuerException), + new StackFrame(true))), + IsValid = false, SecurityToken = JsonUtilities.CreateUnsignedJsonWebToken(JwtRegisteredClaimNames.Iss, issClaim), - ValidationParameters = new TokenValidationParameters() - { - ValidIssuers = [issClaim] - } + ValidationParameters = new ValidationParameters { ValidIssuers = [validIssuer] } }); return theoryData; @@ -202,7 +188,7 @@ public IssuerValidationResultsTheoryData(string testId) : base(testId) public SecurityToken SecurityToken { get; set; } - public TokenValidationParameters ValidationParameters { get; set; } + internal ValidationParameters ValidationParameters { get; set; } internal ValidationFailureType ValidationFailureType { get; set; } } From 2f1d772a20f0b16513a262453a380b311d7f291a Mon Sep 17 00:00:00 2001 From: Franco Fung Date: Wed, 31 Jul 2024 19:00:39 -0700 Subject: [PATCH 2/3] Added test to Validissuers list --- .../Validation/ValidationParametersTests.cs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/test/Microsoft.IdentityModel.Tokens.Tests/Validation/ValidationParametersTests.cs b/test/Microsoft.IdentityModel.Tokens.Tests/Validation/ValidationParametersTests.cs index 7d1a98de4f..9b93c70f50 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 ValidIssuers_GetSet_ValidIssuersList() + { + var validationParameters = new ValidationParameters(); + var validIssuers = new List { "issuer1", "issuer2" }; + + validationParameters.ValidIssuers = validIssuers; + + Assert.Equal(validIssuers, validationParameters.ValidIssuers); + } + + [Fact] + public void ValidIssuers_SetNull_ThrowsArgumentNullException() + { + var validationParameters = new ValidationParameters(); + + Assert.Throws(() => validationParameters.ValidIssuers = null); + } + [Fact] public void ValidTypes_Get_ReturnsValidTokenTypes() { From 74c0145fb408bb78e6b85bfbf6009385589688d5 Mon Sep 17 00:00:00 2001 From: Franco Fung <38921563+FuPingFranco@users.noreply.github.com> Date: Tue, 6 Aug 2024 08:03:23 -0700 Subject: [PATCH 3/3] Addressed PR feedback, updated tests. (#2766) Co-authored-by: Ignacio Inglese --- .../Validation/ValidationParameters.cs | 17 +++--- .../Validation/Validators.Issuer.cs | 2 +- .../Validation/IssuerValidationResultTests.cs | 52 +++++++++---------- .../Validation/ValidationParametersTests.cs | 15 +----- 4 files changed, 35 insertions(+), 51 deletions(-) diff --git a/src/Microsoft.IdentityModel.Tokens/Validation/ValidationParameters.cs b/src/Microsoft.IdentityModel.Tokens/Validation/ValidationParameters.cs index 2c8fbb5d3b..979a26f2b7 100644 --- a/src/Microsoft.IdentityModel.Tokens/Validation/ValidationParameters.cs +++ b/src/Microsoft.IdentityModel.Tokens/Validation/ValidationParameters.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.ComponentModel; using System.Security.Claims; +using System.Threading; using Microsoft.IdentityModel.Abstractions; using Microsoft.IdentityModel.Logging; @@ -20,7 +21,7 @@ internal class ValidationParameters private string _nameClaimType = ClaimsIdentity.DefaultNameClaimType; private string _roleClaimType = ClaimsIdentity.DefaultRoleClaimType; private Dictionary _instancePropertyBag; - private IList _validIssuers = []; + private IList _validIssuers; private IList _validTokenTypes = []; private AlgorithmValidatorDelegate _algorithmValidator = Validators.ValidateAlgorithm; @@ -90,7 +91,7 @@ protected ValidationParameters(ValidationParameters other) ValidateWithLKG = other.ValidateWithLKG; ValidAlgorithms = other.ValidAlgorithms; ValidAudiences = other.ValidAudiences; - ValidIssuers = other.ValidIssuers; + _validIssuers = other.ValidIssuers; ValidTypes = other.ValidTypes; } @@ -518,16 +519,14 @@ public TypeValidatorDelegate TypeValidator public IList ValidAudiences { get; } /// - /// Gets or sets the that contains valid issuers that will be used to check against the token's issuer. + /// Gets the that contains valid issuers that will be used to check against the token's issuer. /// The default is an empty collection. /// - /// Thrown when the value is set as null. /// The that contains valid issuers that will be used to check against the token's 'iss' claim. - public IList ValidIssuers - { - get { return _validIssuers; } - set { _validIssuers = value ?? throw new ArgumentNullException(nameof(value), "ValidIssuers cannot be set as null."); } - } + public IList ValidIssuers => + _validIssuers ?? + Interlocked.CompareExchange(ref _validIssuers, [], null) ?? + _validIssuers; /// /// Gets the that contains valid types that will be used to check against the JWT header's 'typ' claim. diff --git a/src/Microsoft.IdentityModel.Tokens/Validation/Validators.Issuer.cs b/src/Microsoft.IdentityModel.Tokens/Validation/Validators.Issuer.cs index c1cb94a744..602721ea21 100644 --- a/src/Microsoft.IdentityModel.Tokens/Validation/Validators.Issuer.cs +++ b/src/Microsoft.IdentityModel.Tokens/Validation/Validators.Issuer.cs @@ -92,7 +92,7 @@ internal static async Task ValidateIssuerAsync( configuration = await validationParameters.ConfigurationManager.GetBaseConfigurationAsync(cancellationToken).ConfigureAwait(false); // Return failed IssuerValidationResult if all possible places to validate against are null or empty. - if (validationParameters.ValidIssuers.IsNullOrEmpty() && string.IsNullOrWhiteSpace(configuration?.Issuer)) + if (validationParameters.ValidIssuers.Count == 0 && string.IsNullOrWhiteSpace(configuration?.Issuer)) { return new IssuerValidationResult( issuer, diff --git a/test/Microsoft.IdentityModel.Tokens.Tests/Validation/IssuerValidationResultTests.cs b/test/Microsoft.IdentityModel.Tokens.Tests/Validation/IssuerValidationResultTests.cs index b3be4a1a88..bd9ba6185c 100644 --- a/test/Microsoft.IdentityModel.Tokens.Tests/Validation/IssuerValidationResultTests.cs +++ b/test/Microsoft.IdentityModel.Tokens.Tests/Validation/IssuerValidationResultTests.cs @@ -21,29 +21,25 @@ public async Task IssuerValidatorAsyncTests(IssuerValidationResultsTheoryData th { CompareContext context = TestUtilities.WriteHeader($"{this}.IssuerValidatorAsyncTests", theoryData); - try - { - IssuerValidationResult issuerValidationResult = await Validators.ValidateIssuerAsync( - theoryData.Issuer, - theoryData.SecurityToken, - theoryData.ValidationParameters, - new CallContext(), - CancellationToken.None).ConfigureAwait(false); - - if (issuerValidationResult.Exception != null) - theoryData.ExpectedException.ProcessException(issuerValidationResult.Exception, context); - else - theoryData.ExpectedException.ProcessNoException(); - - IdentityComparer.AreIssuerValidationResultsEqual( - issuerValidationResult, - theoryData.IssuerValidationResult, - context); - } - catch (SecurityTokenInvalidIssuerException ex) - { - theoryData.ExpectedException.ProcessException(ex, context); - } + if (theoryData.ValidIssuerToAdd != null) + theoryData.ValidationParameters.ValidIssuers.Add(theoryData.ValidIssuerToAdd); + + IssuerValidationResult issuerValidationResult = await Validators.ValidateIssuerAsync( + theoryData.Issuer, + theoryData.SecurityToken, + theoryData.ValidationParameters, + new CallContext(), + CancellationToken.None).ConfigureAwait(false); + + if (issuerValidationResult.Exception != null) + theoryData.ExpectedException.ProcessException(issuerValidationResult.Exception, context); + else + theoryData.ExpectedException.ProcessNoException(); + + IdentityComparer.AreIssuerValidationResultsEqual( + issuerValidationResult, + theoryData.IssuerValidationResult, + context); TestUtilities.AssertFailIfErrors(context); } @@ -141,10 +137,8 @@ public static TheoryData IssuerValdationResul IssuerValidationResult.ValidationSource.IssuerIsAmongValidIssuers), IsValid = true, SecurityToken = JsonUtilities.CreateUnsignedJsonWebToken(JwtRegisteredClaimNames.Iss, issClaim), - ValidationParameters = new ValidationParameters() - { - ValidIssuers = [issClaim] - } + ValidationParameters = new ValidationParameters(), + ValidIssuerToAdd = issClaim }); theoryData.Add(new IssuerValidationResultsTheoryData("Invalid_Issuer") @@ -164,7 +158,8 @@ public static TheoryData IssuerValdationResul new StackFrame(true))), IsValid = false, SecurityToken = JsonUtilities.CreateUnsignedJsonWebToken(JwtRegisteredClaimNames.Iss, issClaim), - ValidationParameters = new ValidationParameters { ValidIssuers = [validIssuer] } + ValidationParameters = new ValidationParameters(), + ValidIssuerToAdd = validIssuer }); return theoryData; @@ -191,5 +186,6 @@ public IssuerValidationResultsTheoryData(string testId) : base(testId) internal ValidationParameters ValidationParameters { get; set; } internal ValidationFailureType ValidationFailureType { get; set; } + public string ValidIssuerToAdd { get; internal set; } } } diff --git a/test/Microsoft.IdentityModel.Tokens.Tests/Validation/ValidationParametersTests.cs b/test/Microsoft.IdentityModel.Tokens.Tests/Validation/ValidationParametersTests.cs index 9b93c70f50..54ddedd488 100644 --- a/test/Microsoft.IdentityModel.Tokens.Tests/Validation/ValidationParametersTests.cs +++ b/test/Microsoft.IdentityModel.Tokens.Tests/Validation/ValidationParametersTests.cs @@ -21,22 +21,11 @@ public void SetValidators_NullValue_ThrowsArgumentNullException() } [Fact] - public void ValidIssuers_GetSet_ValidIssuersList() + public void ValidIssuers_GetReturnsEmptyList() { var validationParameters = new ValidationParameters(); - var validIssuers = new List { "issuer1", "issuer2" }; - validationParameters.ValidIssuers = validIssuers; - - Assert.Equal(validIssuers, validationParameters.ValidIssuers); - } - - [Fact] - public void ValidIssuers_SetNull_ThrowsArgumentNullException() - { - var validationParameters = new ValidationParameters(); - - Assert.Throws(() => validationParameters.ValidIssuers = null); + Assert.Equal(0, validationParameters.ValidIssuers.Count); } [Fact]