Skip to content

Commit

Permalink
Remove explicit locking in OpenIdConnectCachingSecurityTokenProvider (#…
Browse files Browse the repository at this point in the history
…3202)

* Remove explicit locking in OpenIdConnectCachingSecurityTokenProvider

Fixes #3078

See #3124 and #3118 for more context.

* Simplify OpenIdConnectCachingSecurityTokenProvider

---------

Co-authored-by: Keegan Caruso <[email protected]>
  • Loading branch information
keegan-caruso and Keegan Caruso authored Jan 17, 2025
1 parent 5a5f59b commit c116563
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 54 deletions.
1 change: 1 addition & 0 deletions src/Microsoft.Identity.Web.OWIN/InternalAPI.Unshipped.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
readonly Microsoft.Identity.Web.OpenIdConnectCachingSecurityTokenProvider._configManager -> Microsoft.IdentityModel.Protocols.ConfigurationManager<Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectConfiguration!>!
Original file line number Diff line number Diff line change
@@ -1,30 +1,22 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using System.Collections.Generic;
using Microsoft.IdentityModel.Protocols;
using Microsoft.IdentityModel.Protocols.OpenIdConnect;
using Microsoft.IdentityModel.Tokens;
using Microsoft.Owin.Security.Jwt;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;

namespace Microsoft.Identity.Web
{
// This class is necessary because the OAuthBearer Middleware does not leverage
// the OpenID Connect metadata endpoint exposed by the STS by default.
internal class OpenIdConnectCachingSecurityTokenProvider : IIssuerSecurityKeyProvider
{
public ConfigurationManager<OpenIdConnectConfiguration> _configManager;
private string? _issuer;
private IEnumerable<SecurityKey>? _keys;
private readonly string _metadataEndpoint;

private readonly ReaderWriterLockSlim _synclock = new ReaderWriterLockSlim();
public readonly ConfigurationManager<OpenIdConnectConfiguration> _configManager;

public OpenIdConnectCachingSecurityTokenProvider(string metadataEndpoint)
{
_metadataEndpoint = metadataEndpoint;
_configManager = new ConfigurationManager<OpenIdConnectConfiguration>(metadataEndpoint, new OpenIdConnectConfigurationRetriever());

RetrieveMetadata();
Expand All @@ -36,61 +28,23 @@ public OpenIdConnectCachingSecurityTokenProvider(string metadataEndpoint)
/// <value>
/// The issuer the credentials are for.
/// </value>
public string? Issuer
{
get
{
RetrieveMetadata();
_synclock.EnterReadLock();
try
{
return _issuer;
}
finally
{
_synclock.ExitReadLock();
}
}
}
public string? Issuer => RetrieveMetadata().Issuer;

/// <summary>
/// Gets all known security keys.
/// </summary>
/// <value>
/// All known security keys.
/// </value>
public IEnumerable<SecurityKey>? SecurityKeys
{
get
{
RetrieveMetadata();
_synclock.EnterReadLock();
try
{
return _keys;
}
finally
{
_synclock.ExitReadLock();
}
}
}
public IEnumerable<SecurityKey>? SecurityKeys => RetrieveMetadata().SigningKeys;

private void RetrieveMetadata()
private OpenIdConnectConfiguration RetrieveMetadata()
{
_synclock.EnterWriteLock();
try
{
// ConfigurationManager will return the same cached config unless enough time has passed,
// then the return value will be a new object.
#pragma warning disable VSTHRD002 // Avoid problematic synchronous waits
OpenIdConnectConfiguration config = Task.Run(_configManager.GetConfigurationAsync).Result;
return _configManager.GetConfigurationAsync().Result;
#pragma warning restore VSTHRD002 // Avoid problematic synchronous waits
_issuer = config.Issuer;
_keys = config.SigningKeys;
}
finally
{
_synclock.ExitWriteLock();
}
}
}
}

0 comments on commit c116563

Please sign in to comment.