从元数据端点缓存颁发者和密钥

时间:2018-07-04 22:06:24

标签: azure-active-directory identity azure-ad-b2c

我遵循了使用Azure AD B2C从ASP.NET Web应用程序调用ASP.NET Web API的示例: https://github.com/Azure-Samples/active-directory-b2c-dotnet-webapp-and-webapi

我对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();
        }
    }
}

元数据端点:

https://login.microsoftonline.com/{TENANT}.onmicrosoft.com/v2.0/.well-known/openid-configuration?p={POLICY}

为什么我们总是需要打电话来检索密钥和发行者?

我可以缓存这些值吗? 如果是,那么到期的最佳设置是什么?

1 个答案:

答案 0 :(得分:1)

  

为什么我们总是需要打电话找回钥匙和   发行人?

  • 签名密钥:您的应用必须使用此签名密钥(公共密钥)来验证AAD使用其私钥签名的令牌。该元数据端点包含特定时刻正在使用的所有公钥信息:

    https://login.microsoftonline.com/<yourtenantdomain>/discovery/v2.0/keys?p=<SigninPolicyName>

  • 颁发者:您的应用程序需要颁发者来验证令牌的iss声明以信任此令牌。还可以从OpenID连接元数据端点检索发布者:

    https://login.microsoftonline.com/<YourTenantDomain>/v2.0/.well-known/openid-configuration?p=<SigninPolicyName>

  

标识构造和创建的安全令牌服务(STS)。   返回令牌。在Azure AD返回的令牌中,发行方为   sts.windows.net。颁发者声明值中的GUID是租户ID   Azure AD目录。租户ID是一成不变且可靠的   目录的标识符。

此外,OAuthBearer Middleware默认情况下不使用此元数据终结点,因此您需要使用代码来检索它。 因此,您必须检索密钥和发行者以验证令牌。

  

我可以缓存这些值吗?如果是,最适合的设置是什么   到期?

是的,使用您发布的代码,它们会将这些值缓存在configManager.GetConfigurationAsync中,而OpenIdConnectCachingSecurityTokenProvider在启动时会使用它们。

关于有效期:签名密钥可以翻转。因此,不必担心演唱键的设置有效期。重要的是您最好动态获取元数据位置,以保持签名密钥正确。

参考:

您可以在this documentaion中查看有关验证B2C令牌签名的详细信息。

this documentation中了解有关在AAD中签名密钥翻转的更多详细信息。

查看有关OpendID提供者元数据的更多详细信息:http://openid.net/specs/openid-connect-discovery-1_0.html#ProviderMetadata