I followed the sample for calling an ASP.NET Web API from an ASP.NET Web App using the Azure AD B2C: https://github.com/Azure-Samples/active-directory-b2c-dotnet-webapp-and-webapi
I've a question regarding the OpenIdConnectCachingSecurityTokenProvider
// This class is necessary because the OAuthBearer Middleware does not leverage
// the OpenID Connect metadata endpoint exposed by the STS by default.
public 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 OpenIdConnectCachingSecurityTokenProvider(string metadataEndpoint)
{
_metadataEndpoint = metadataEndpoint;
_configManager = new ConfigurationManager<OpenIdConnectConfiguration>(metadataEndpoint, new OpenIdConnectConfigurationRetriever());
RetrieveMetadata();
}
/// <summary>
/// Gets the issuer the credentials are for.
/// </summary>
/// <value>
/// The issuer the credentials are for.
/// </value>
public string Issuer
{
get
{
RetrieveMetadata();
_synclock.EnterReadLock();
try
{
return _issuer;
}
finally
{
_synclock.ExitReadLock();
}
}
}
/// <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();
}
}
}
private void RetrieveMetadata()
{
_synclock.EnterWriteLock();
try
{
OpenIdConnectConfiguration config = Task.Run(_configManager.GetConfigurationAsync).Result;
_issuer = config.Issuer;
_keys = config.SigningKeys;
}
finally
{
_synclock.ExitWriteLock();
}
}
}
The metadata endpoint:
https://login.microsoftonline.com/{TENANT}.onmicrosoft.com/v2.0/.well-known/openid-configuration?p={POLICY}
Why all the time we need to make a call to retrieve the keys and the issuer?
Can I cache these values? If yes, what's the best setting for the expiration?
Why all the time we need to make a call to retrieve the keys and the issuer?
Signing key: Your app must use this signing key(public key) to validate the token which is signed by AAD using its private key. This metadata endpoint contains all the public key information in use at the particular moment:
https://login.microsoftonline.com/<yourtenantdomain>/discovery/v2.0/keys?p=<SigninPolicyName>
Issuer : Your application needs Issuer to validate the token's iss
claim to trust this token. Issuer can be also retrieved from the OpenID connect metadata endpoint:
https://login.microsoftonline.com/<YourTenantDomain>/v2.0/.well-known/openid-configuration?p=<SigninPolicyName>
Identifies the security token service (STS) that constructs and returns the token. In the tokens that Azure AD returns, the issuer is sts.windows.net. The GUID in the Issuer claim value is the tenant ID of the Azure AD directory. The tenant ID is an immutable and reliable identifier of the directory.
Also,OAuthBearer Middleware
doesn't leverage this metadata endpoint by default, so you need to retrieve it with code. So, you must retrieve the keys and the issuer to validate the token.
Can I cache these values? If yes, what's the best setting for the expiration?
Yes, with the code you post, it cache these values in configManager.GetConfigurationAsync
and OpenIdConnectCachingSecurityTokenProvider
use it when starting up.
About the expiration: Signing key can roll over. So, don't worry about the set expiration for the singing key. The important thing is that you'd better to fetch the metadata location dynamically to keep the signing key is the correct.
Reference:
You can see the details about Validate the signature of B2C tokens in this documentaion.
See more details about Signing key rollover in AAD in this documentation.
See more details about OpendID Provider Metadata :http://openid.net/specs/openid-connect-discovery-1_0.html#ProviderMetadata
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With