首页 > 解决方案 > 在 Azure Function 中缓存公共 JWT 身份验证密钥

问题描述

我有一个带有各种端点的 Azure 函数 .NET core 2.1。

对于身份验证,我有一个外部安全提供程序,我需要从中检索发现文档(元数据),然后才能验证请求的令牌。

当前每次发出单个请求时都会加载该文档:

var discoveryDocument = await configurationManager.GetConfigurationAsync();

现在我自然不想对每个请求都进行此调用,因为文档很少更改。

另一方面,Azure 函数是无状态的。我听说ConfigurationManager.GetConfigurationAsync()是以某种方式缓存检索到的数据,但我找不到更多信息。目前,我最终得到了一个在启动时触发的函数,检索文档并将其存储在本地文件系统中。因此,当发出请求时,我会再次读取文件,以避免再次请求获取公钥。

有这方面的经验吗?

解决方案:

我可以按照@juunas 的建议使用静态类来解决它。对于每一个功能,我都在重复使用该ValidateToken()方法。每隔一段时间就会调用一次发现文档(当IConfigurationManager认为它需要刷新时),因为它会自动缓存。

class AuthConfig
{
    static readonly IConfigurationManager<OpenIdConnectConfiguration> _configurationManager;

    static AuthConfig()
    {
        _configurationManager = new ConfigurationManager<OpenIdConnectConfiguration>(
            "<CONFIGURL>",
            new OpenIdConnectConfigurationRetriever(),
            new HttpDocumentRetriever());
    }

    public static async Task<MyUserEntity> ValidateToken(string token)
    {
        var discoveryDocument = await _configurationManager.GetConfigurationAsync(CancellationToken.None);

        var validationParameters = new TokenValidationParameters
        {
            RequireExpirationTime = true,
            RequireSignedTokens = true,
            ValidateIssuerSigningKey = true,
            IssuerSigningKeys = discoveryDocument.SigningKeys,
            ValidateLifetime = true,
            ValidateAudience = false,
            ValidateIssuer = true,
            ValidIssuer = discoveryDocument.Issuer
        };

        try
        {
            var claimsPrincipal = new JwtSecurityTokenHandler().ValidateToken(token, validationParameters, out var rawValidatedToken);
            var user = ParseMyUserEntity(claimsPrincipal);
            return user;
        }
        catch
        {
            return null;
        }
    }
}

标签: azurejwtazure-functionsasp.net-core-2.1

解决方案


您可以将数据存储在静态字段中(也可以在单独的静态类中)。

That should work as an in-memory cache on that function instance at least. If the function gets scaled to multiple instances, their caches will be separated.


推荐阅读