diff --git a/build/version.props b/build/version.props index b1584b52e5..3df8f8c14c 100644 --- a/build/version.props +++ b/build/version.props @@ -1,6 +1,6 @@ - + 8.0.1 @@ -14,4 +14,4 @@ $(MicrosoftIdentityModelVersion).$([System.DateTime]::Now.AddYears(-2019).Year)$([System.DateTime]::Now.ToString("MMdd")) $(MicrosoftIdentityModelCurrentVersion).$([System.DateTime]::Now.AddYears(-2019).Year)$([System.DateTime]::Now.ToString("MMdd")) - \ No newline at end of file + diff --git a/src/Microsoft.IdentityModel.Tokens/CryptoProviderFactory.cs b/src/Microsoft.IdentityModel.Tokens/CryptoProviderFactory.cs index 4bfcad5437..bdbe960b47 100644 --- a/src/Microsoft.IdentityModel.Tokens/CryptoProviderFactory.cs +++ b/src/Microsoft.IdentityModel.Tokens/CryptoProviderFactory.cs @@ -16,7 +16,6 @@ public class CryptoProviderFactory { private static CryptoProviderFactory _default; private static readonly ConcurrentDictionary _typeToAlgorithmMap = new ConcurrentDictionary(); - private static readonly object _cacheLock = new object(); private static int _defaultSignatureProviderObjectPoolCacheSize = Environment.ProcessorCount * 4; private static string _typeofAsymmetricSignatureProvider = typeof(AsymmetricSignatureProvider).ToString(); private static string _typeofSymmetricSignatureProvider = typeof(SymmetricSignatureProvider).ToString(); @@ -591,25 +590,23 @@ private SignatureProvider CreateSignatureProvider(SecurityKey key, string algori return signatureProvider; } - lock (_cacheLock) - { - if (CryptoProviderCache.TryGetSignatureProvider(key, algorithm, typeofSignatureProvider, willCreateSignatures, out signatureProvider)) - { - signatureProvider.AddRef(); - return signatureProvider; - } - - if (!IsSupportedAlgorithm(algorithm, key)) - throw LogHelper.LogExceptionMessage(new NotSupportedException(LogHelper.FormatInvariant(LogMessages.IDX10634, LogHelper.MarkAsNonPII(algorithm), key))); + if (!IsSupportedAlgorithm(algorithm, key)) + throw LogHelper.LogExceptionMessage(new NotSupportedException(LogHelper.FormatInvariant(LogMessages.IDX10634, LogHelper.MarkAsNonPII(algorithm), key))); - if (createAsymmetric) - signatureProvider = new AsymmetricSignatureProvider(key, algorithm, willCreateSignatures, this); - else - signatureProvider = new SymmetricSignatureProvider(key, algorithm, willCreateSignatures); + if (createAsymmetric) + signatureProvider = new AsymmetricSignatureProvider(key, algorithm, willCreateSignatures, this); + else + signatureProvider = new SymmetricSignatureProvider(key, algorithm, willCreateSignatures); - if (ShouldCacheSignatureProvider(signatureProvider)) - signatureProvider.IsCached = CryptoProviderCache.TryAdd(signatureProvider); - } + if (ShouldCacheSignatureProvider(signatureProvider)) + // CryptoProviderCache.TryAdd will return false if unable to add the SignatureProvider. + // One possibility is the SignatureProvider was added between when we called TryGetSignatureProvider and here. + // SignatureProvider.IsCached will be false and CryptoProviderFactory.Release will dispose the SignatureProvider. + // Since the SignatueProvider, was never added to the cache, TryGetSignatureProvider will not return this instance, we can dispose. + // This will result in sometimes (rarely) creating a SignatureProvider that is never cached. + // The alternative is to use a lock after the call to TryGetSignatureProvider, and then check again: { TryGet, lock, TryGet }. + // This will result in excesive locking for different keys, which is common in POP scenarios. + signatureProvider.IsCached = CryptoProviderCache.TryAdd(signatureProvider); } else {