diff --git a/src/Microsoft.IdentityModel.JsonWebTokens/JwtTokenUtilities.cs b/src/Microsoft.IdentityModel.JsonWebTokens/JwtTokenUtilities.cs index f24e2f4fd2..d8bae3878a 100644 --- a/src/Microsoft.IdentityModel.JsonWebTokens/JwtTokenUtilities.cs +++ b/src/Microsoft.IdentityModel.JsonWebTokens/JwtTokenUtilities.cs @@ -538,7 +538,6 @@ internal static JsonDocument GetJsonDocumentFromBase64UrlEncodedString(string ra return Base64UrlEncoding.Decode(rawString, startIndex, length, ParseDocument); } #endif - } } diff --git a/src/Microsoft.IdentityModel.Tokens/AppContextSwitches.cs b/src/Microsoft.IdentityModel.Tokens/AppContextSwitches.cs index db3b8e269e..3e8b0bf066 100644 --- a/src/Microsoft.IdentityModel.Tokens/AppContextSwitches.cs +++ b/src/Microsoft.IdentityModel.Tokens/AppContextSwitches.cs @@ -11,14 +11,46 @@ namespace Microsoft.IdentityModel.Tokens /// internal static class AppContextSwitches { +#if NET461_OR_GREATER || NETCOREAPP || NETSTANDARD /// /// Enables a new behavior of using instead of globally. /// internal const string UseCaseSensitiveClaimsIdentityTypeSwitch = "Microsoft.IdentityModel.Tokens.UseCaseSensitiveClaimsIdentityType"; -#if NET46_OR_GREATER || NETCOREAPP || NETSTANDARD - internal static bool UseCaseSensitiveClaimsIdentityType() => AppContext.TryGetSwitch(UseCaseSensitiveClaimsIdentityTypeSwitch, out bool useCaseSensitiveClaimsIdentityType) && useCaseSensitiveClaimsIdentityType; + private static bool? _useCaseSensitiveClaimsIdentityType; + internal static bool UseCaseSensitiveClaimsIdentityType => _useCaseSensitiveClaimsIdentityType ??= (AppContext.TryGetSwitch(UseCaseSensitiveClaimsIdentityTypeSwitch, out bool useCaseSensitiveClaimsIdentityType) && useCaseSensitiveClaimsIdentityType); + + /// + /// When validating the issuer signing key, specifies whether to fail if the 'tid' claim is missing. + /// + internal const string DoNotFailOnMissingTidSwitch = "Switch.Microsoft.IdentityModel.DontFailOnMissingTidValidateIssuerSigning"; + + private static bool? _doNotFailOnMissingTid; + + internal static bool DoNotFailOnMissingTid => _doNotFailOnMissingTid ??= (AppContext.TryGetSwitch(DoNotFailOnMissingTidSwitch, out bool doNotFailOnMissingTid) && doNotFailOnMissingTid); + + + internal const string SkipValidationOfHmacKey = "Switch.Microsoft.IdentityModel.UnsafeRelaxHmacKeySizeValidation"; + + private static bool? _skipValidationOfHmacKeySizes; + + internal static bool SkipValidationOfHmacKeySizes => _skipValidationOfHmacKeySizes ??= (AppContext.TryGetSwitch(SkipValidationOfHmacKey, out bool skipValidationOfHmacKeySizes) && skipValidationOfHmacKeySizes); + + /// + /// Used for testing to reset all switches to its default value. + /// + internal static void ResetAllSwitches() + { + _useCaseSensitiveClaimsIdentityType = null; + AppContext.SetSwitch(UseCaseSensitiveClaimsIdentityTypeSwitch, false); + + _doNotFailOnMissingTid = null; + AppContext.SetSwitch(DoNotFailOnMissingTidSwitch, false); + + _skipValidationOfHmacKeySizes = null; + AppContext.SetSwitch(SkipValidationOfHmacKey, false); + } #else // .NET 4.5 does not support AppContext switches. Always use ClaimsIdentity. internal static bool UseCaseSensitiveClaimsIdentityType() => false; diff --git a/src/Microsoft.IdentityModel.Tokens/ClaimsIdentityFactory.cs b/src/Microsoft.IdentityModel.Tokens/ClaimsIdentityFactory.cs index 1f6f56bc74..9adc31891d 100644 --- a/src/Microsoft.IdentityModel.Tokens/ClaimsIdentityFactory.cs +++ b/src/Microsoft.IdentityModel.Tokens/ClaimsIdentityFactory.cs @@ -6,14 +6,21 @@ namespace Microsoft.IdentityModel.Tokens { +#if !NET45 /// - /// Facilitates the creation of and instances based on the . + /// Facilitates the creation of and instances based on the . /// +#endif + internal static class ClaimsIdentityFactory { internal static ClaimsIdentity Create(IEnumerable claims) { +#if NET45 if (AppContextSwitches.UseCaseSensitiveClaimsIdentityType()) +#else + if (AppContextSwitches.UseCaseSensitiveClaimsIdentityType) +#endif return new CaseSensitiveClaimsIdentity(claims); return new ClaimsIdentity(claims); @@ -21,7 +28,11 @@ internal static ClaimsIdentity Create(IEnumerable claims) internal static ClaimsIdentity Create(IEnumerable claims, string authenticationType) { +#if NET45 if (AppContextSwitches.UseCaseSensitiveClaimsIdentityType()) +#else + if (AppContextSwitches.UseCaseSensitiveClaimsIdentityType) +#endif return new CaseSensitiveClaimsIdentity(claims, authenticationType); return new ClaimsIdentity(claims, authenticationType); @@ -29,12 +40,15 @@ internal static ClaimsIdentity Create(IEnumerable claims, string authenti internal static ClaimsIdentity Create(string authenticationType, string nameType, string roleType, SecurityToken securityToken) { +#if NET45 if (AppContextSwitches.UseCaseSensitiveClaimsIdentityType()) +#else + if (AppContextSwitches.UseCaseSensitiveClaimsIdentityType) +#endif return new CaseSensitiveClaimsIdentity(authenticationType: authenticationType, nameType: nameType, roleType: roleType) { SecurityToken = securityToken, }; - return new ClaimsIdentity(authenticationType: authenticationType, nameType: nameType, roleType: roleType); } } diff --git a/src/Microsoft.IdentityModel.Tokens/CryptoProviderFactory.cs b/src/Microsoft.IdentityModel.Tokens/CryptoProviderFactory.cs index 6b3243c11f..074416d995 100644 --- a/src/Microsoft.IdentityModel.Tokens/CryptoProviderFactory.cs +++ b/src/Microsoft.IdentityModel.Tokens/CryptoProviderFactory.cs @@ -19,9 +19,7 @@ public class CryptoProviderFactory private static object _cacheLock = new object(); private static int _defaultSignatureProviderObjectPoolCacheSize = Environment.ProcessorCount * 4; private int _signatureProviderObjectPoolCacheSize = _defaultSignatureProviderObjectPoolCacheSize; -#if !NET45 - internal const string _skipValidationOfHmacKeySizes = "Switch.Microsoft.IdentityModel.UnsafeRelaxHmacKeySizeValidation"; -#endif + /// /// Returns the default instance. /// @@ -492,7 +490,7 @@ public virtual KeyedHashAlgorithm CreateKeyedHashAlgorithm(byte[] keyBytes, stri private static void ValidateKeySize(byte[] keyBytes, string algorithm, int expectedNumberOfBytes) { #if !NET45 - if (AppContext.TryGetSwitch(_skipValidationOfHmacKeySizes, out bool skipValidationOfHmacKeySize) && skipValidationOfHmacKeySize) + if (AppContextSwitches.SkipValidationOfHmacKeySizes) return; #endif if (keyBytes.Length < expectedNumberOfBytes) diff --git a/src/Microsoft.IdentityModel.Validators/AadTokenValidationParametersExtension.cs b/src/Microsoft.IdentityModel.Validators/AadTokenValidationParametersExtension.cs index 1a0e132dfd..03bd391a7f 100644 --- a/src/Microsoft.IdentityModel.Validators/AadTokenValidationParametersExtension.cs +++ b/src/Microsoft.IdentityModel.Validators/AadTokenValidationParametersExtension.cs @@ -44,15 +44,6 @@ public static void EnableAadSigningKeyIssuerValidation(this TokenValidationParam }; } -#if !NET45 - internal const string DontFailOnMissingTidSwitch = "Switch.Microsoft.IdentityModel.DontFailOnMissingTidValidateIssuerSigning"; - - private static bool DontFailOnMissingTid() - { - return (AppContext.TryGetSwitch(DontFailOnMissingTidSwitch, out bool dontFailOnMissingTid) && dontFailOnMissingTid); - } -#endif - /// /// Validates the issuer signing key. /// @@ -83,10 +74,9 @@ internal static bool ValidateIssuerSigningKey(SecurityKey securityKey, SecurityT if (string.IsNullOrEmpty(tenantIdFromToken)) { #if !NET45 - if (DontFailOnMissingTid()) + if (AppContextSwitches.DoNotFailOnMissingTid) return true; #endif - throw LogHelper.LogExceptionMessage(new SecurityTokenInvalidIssuerException(LogMessages.IDX40009)); } diff --git a/test/Microsoft.IdentityModel.JsonWebTokens.Tests/JsonWebTokenHandlerClaimsIdentityTests.cs b/test/Microsoft.IdentityModel.JsonWebTokens.Tests/JsonWebTokenHandlerClaimsIdentityTests.cs index 44e8854332..0089fc6cbe 100644 --- a/test/Microsoft.IdentityModel.JsonWebTokens.Tests/JsonWebTokenHandlerClaimsIdentityTests.cs +++ b/test/Microsoft.IdentityModel.JsonWebTokens.Tests/JsonWebTokenHandlerClaimsIdentityTests.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. using System; @@ -41,7 +41,7 @@ public void CreateClaimsIdentity_ReturnsCaseSensitveClaimsIdentity_WithAppContex Assert.IsType(actualClaimsIdentity); Assert.NotNull(((CaseSensitiveClaimsIdentity)actualClaimsIdentity).SecurityToken); - AppContext.SetSwitch(AppContextSwitches.UseCaseSensitiveClaimsIdentityTypeSwitch, false); + AppContextSwitches.ResetAllSwitches(); } #endif @@ -58,6 +58,9 @@ public void CreateClaimsIdentity_ReturnsClaimsIdentity_ByDefault() // This will also test mapped claims flow. handler.MapInboundClaims = true; Assert.IsType(handler.CreateClaimsIdentityInternal(jsonWebToken, tokenValidationParameters, Default.Issuer)); +#if !NET452 + AppContextSwitches.ResetAllSwitches(); +#endif } private class DerivedJsonWebTokenHandler : JsonWebTokenHandler diff --git a/test/Microsoft.IdentityModel.Protocols.OpenIdConnect.Tests/OpenIdConnectMessageTests.cs b/test/Microsoft.IdentityModel.Protocols.OpenIdConnect.Tests/OpenIdConnectMessageTests.cs index f4e9423925..14fa2e7adf 100644 --- a/test/Microsoft.IdentityModel.Protocols.OpenIdConnect.Tests/OpenIdConnectMessageTests.cs +++ b/test/Microsoft.IdentityModel.Protocols.OpenIdConnect.Tests/OpenIdConnectMessageTests.cs @@ -218,7 +218,7 @@ public void OidcCreateAuthenticationRequestUrl(string testId, OpenIdConnectMessa TestUtilities.WriteHeader(testId, "OidcCreateAuthenticationRequestUrl", true); var context = new CompareContext(); // there is no net452 target, we bind to net45 -#if NET452 +#if NET45 if(!message.SkuTelemetryValue.Equals("ID_NET45")) context.Diffs.Add($"{message.SkuTelemetryValue} != ID_NET45"); #elif NET461 @@ -494,7 +494,7 @@ public void OidcCreateLogoutRequestUrl(string testId, OpenIdConnectMessage messa var context = new CompareContext(); // there is no net452 target, we bind to net45 -#if NET452 +#if NET45 if (!message.SkuTelemetryValue.Equals("ID_NET45")) context.Diffs.Add($"{message.SkuTelemetryValue} != ID_NET45"); #elif NET461 @@ -505,7 +505,7 @@ public void OidcCreateLogoutRequestUrl(string testId, OpenIdConnectMessage messa context.Diffs.Add($"{message.SkuTelemetryValue} != ID_NET472"); #elif NET6_0 if (!message.SkuTelemetryValue.Equals("ID_NET6_0")) - context.Diffs.Add($"{message.SkuTelemetryValue} != ID_NETCOREAPP3_1"); + context.Diffs.Add($"{message.SkuTelemetryValue} != ID_NET6_0"); #elif NET_CORE if (!message.SkuTelemetryValue.Equals("ID_NETSTANDARD2_0")) context.Diffs.Add($"{message.SkuTelemetryValue} != ID_NETSTANDARD2_0"); diff --git a/test/Microsoft.IdentityModel.Tokens.Tests/ClaimsIdentityFactoryTests.cs b/test/Microsoft.IdentityModel.Tokens.Tests/ClaimsIdentityFactoryTests.cs index f17deeae91..169ea80e36 100644 --- a/test/Microsoft.IdentityModel.Tokens.Tests/ClaimsIdentityFactoryTests.cs +++ b/test/Microsoft.IdentityModel.Tokens.Tests/ClaimsIdentityFactoryTests.cs @@ -44,7 +44,7 @@ public void Create_FromTokenValidationParameters_ReturnsCorrectClaimsIdentity(bo Assert.IsType(actualClaimsIdentity); } - AppContext.SetSwitch(AppContextSwitches.UseCaseSensitiveClaimsIdentityTypeSwitch, false); + AppContextSwitches.ResetAllSwitches(); } [Theory] diff --git a/test/Microsoft.IdentityModel.Tokens.Tests/SignatureProviderTests.cs b/test/Microsoft.IdentityModel.Tokens.Tests/SignatureProviderTests.cs index 53b3313d65..506cb464b8 100644 --- a/test/Microsoft.IdentityModel.Tokens.Tests/SignatureProviderTests.cs +++ b/test/Microsoft.IdentityModel.Tokens.Tests/SignatureProviderTests.cs @@ -745,7 +745,7 @@ public void SymmetricSecurityKeySizesSign(SymmetricSignatureProviderTheoryData t [Theory, MemberData(nameof(SymmetricSecurityKeySizesVerifyOFFTheoryData))] public void SymmetricSecurityKeySizesVerifyOFF(SymmetricSignatureProviderTheoryData theoryData) { - AppContext.SetSwitch(CryptoProviderFactory._skipValidationOfHmacKeySizes, true); + AppContext.SetSwitch(AppContextSwitches.SkipValidationOfHmacKey, true); var context = TestUtilities.WriteHeader($"{this}.SymmetricSecurityKeySizes", theoryData); try { @@ -759,7 +759,7 @@ public void SymmetricSecurityKeySizesVerifyOFF(SymmetricSignatureProviderTheoryD theoryData.ExpectedException.ProcessException(ex, context); } - AppContext.SetSwitch(CryptoProviderFactory._skipValidationOfHmacKeySizes, false); + AppContextSwitches.ResetAllSwitches(); TestUtilities.AssertFailIfErrors(context); } diff --git a/test/Microsoft.IdentityModel.Validators.Tests/AadSigningKeyIssuerValidatorTests.cs b/test/Microsoft.IdentityModel.Validators.Tests/AadSigningKeyIssuerValidatorTests.cs index 3da5af997c..f7503bc1ec 100644 --- a/test/Microsoft.IdentityModel.Validators.Tests/AadSigningKeyIssuerValidatorTests.cs +++ b/test/Microsoft.IdentityModel.Validators.Tests/AadSigningKeyIssuerValidatorTests.cs @@ -181,7 +181,11 @@ public void ValidateIssuerSigningKeyTests(AadSigningKeyIssuerTheoryData theoryDa } finally { +#if !NET452 + AppContextSwitches.ResetAllSwitches(); +#else theoryData.TearDownAction?.Invoke(); +#endif } TestUtilities.AssertFailIfErrors(context); @@ -346,8 +350,8 @@ public static TheoryData ValidateIssuerSigningKey SecurityKey = KeyingMaterial.JsonWebKeyP256, SecurityToken = new JwtSecurityToken(), OpenIdConnectConfiguration = mockConfiguration, - SetupAction = () => AppContext.SetSwitch(AadTokenValidationParametersExtension.DontFailOnMissingTidSwitch, true), - TearDownAction = () => AppContext.SetSwitch(AadTokenValidationParametersExtension.DontFailOnMissingTidSwitch, false) + SetupAction = () => AppContext.SetSwitch(AppContextSwitches.DoNotFailOnMissingTidSwitch, true), + TearDownAction = () => AppContext.SetSwitch(AppContextSwitches.DoNotFailOnMissingTidSwitch, false) }); theoryData.Add(new AadSigningKeyIssuerTheoryData @@ -357,8 +361,8 @@ public static TheoryData ValidateIssuerSigningKey SecurityToken = new JwtSecurityToken(), OpenIdConnectConfiguration = mockConfiguration, ExpectedException = ExpectedException.SecurityTokenInvalidIssuerException("IDX40009"), - SetupAction = () => AppContext.SetSwitch(AadTokenValidationParametersExtension.DontFailOnMissingTidSwitch, false), - TearDownAction = () => AppContext.SetSwitch(AadTokenValidationParametersExtension.DontFailOnMissingTidSwitch, isEnabled: false) + SetupAction = () => AppContext.SetSwitch(AppContextSwitches.DoNotFailOnMissingTidSwitch, false), + TearDownAction = () => AppContext.SetSwitch(AppContextSwitches.DoNotFailOnMissingTidSwitch, isEnabled: false) }); theoryData.Add(new AadSigningKeyIssuerTheoryData @@ -367,8 +371,8 @@ public static TheoryData ValidateIssuerSigningKey SecurityKey = KeyingMaterial.JsonWebKeyP256, SecurityToken = new JwtSecurityToken(), OpenIdConnectConfiguration = mockConfiguration, - SetupAction = () => AppContext.SetSwitch(AadTokenValidationParametersExtension.DontFailOnMissingTidSwitch, true), - TearDownAction = () => AppContext.SetSwitch(AadTokenValidationParametersExtension.DontFailOnMissingTidSwitch, false) + SetupAction = () => AppContext.SetSwitch(AppContextSwitches.DoNotFailOnMissingTidSwitch, true), + TearDownAction = () => AppContext.SetSwitch(AppContextSwitches.DoNotFailOnMissingTidSwitch, false) }); theoryData.Add(new AadSigningKeyIssuerTheoryData @@ -378,8 +382,8 @@ public static TheoryData ValidateIssuerSigningKey SecurityToken = new JsonWebToken(Default.Jwt(Default.SecurityTokenDescriptor(Default.SymmetricSigningCredentials, [issClaim]))), OpenIdConnectConfiguration = mockConfiguration, ExpectedException = ExpectedException.SecurityTokenInvalidIssuerException("IDX40009"), - SetupAction = () => AppContext.SetSwitch(AadTokenValidationParametersExtension.DontFailOnMissingTidSwitch, false), - TearDownAction = () => AppContext.SetSwitch(AadTokenValidationParametersExtension.DontFailOnMissingTidSwitch, isEnabled: false) + SetupAction = () => AppContext.SetSwitch(AppContextSwitches.DoNotFailOnMissingTidSwitch, false), + TearDownAction = () => AppContext.SetSwitch(AppContextSwitches.DoNotFailOnMissingTidSwitch, isEnabled: false) }); theoryData.Add(new AadSigningKeyIssuerTheoryData @@ -388,8 +392,8 @@ public static TheoryData ValidateIssuerSigningKey SecurityKey = KeyingMaterial.JsonWebKeyP256, SecurityToken = new JsonWebToken(Default.Jwt(Default.SecurityTokenDescriptor(Default.SymmetricSigningCredentials, [issClaim]))), OpenIdConnectConfiguration = mockConfiguration, - SetupAction = () => AppContext.SetSwitch(AadTokenValidationParametersExtension.DontFailOnMissingTidSwitch, true), - TearDownAction = () => AppContext.SetSwitch(AadTokenValidationParametersExtension.DontFailOnMissingTidSwitch, false) + SetupAction = () => AppContext.SetSwitch(AppContextSwitches.DoNotFailOnMissingTidSwitch, true), + TearDownAction = () => AppContext.SetSwitch(AppContextSwitches.DoNotFailOnMissingTidSwitch, false) }); #endif diff --git a/test/System.IdentityModel.Tokens.Jwt.Tests/CreateAndValidateTokens.cs b/test/System.IdentityModel.Tokens.Jwt.Tests/CreateAndValidateTokens.cs index 05b9bee2fc..c38e5e52de 100644 --- a/test/System.IdentityModel.Tokens.Jwt.Tests/CreateAndValidateTokens.cs +++ b/test/System.IdentityModel.Tokens.Jwt.Tests/CreateAndValidateTokens.cs @@ -615,8 +615,8 @@ public static TheoryData RoundTripTokensTheoryData() ValidationParameters = Default.SymmetricEncryptSignTokenValidationParameters }); -#if NET461 || NET462 || NET_CORE - // RsaPss is not supported on .NET < 4.6 +#if NET462 || NET_CORE + // RsaPss is not supported on .NET < 4.6.2 var rsaPssSigningCredentials = new SigningCredentials(Default.AsymmetricSigningKey, SecurityAlgorithms.RsaSsaPssSha256); theoryData.Add(new JwtTheoryData {