温馨提示:本文翻译自stackoverflow.com,查看原文请点击:其他 - Caching public JWT authentication keys in Azure Function
azure azure-functions jwt asp.net-core-2.1

其他 - 在Azure函数中缓存公共JWT身份验证密钥

发布于 2020-03-27 16:03:34

我有一个具有各种终结点的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;
        }
    }
}

查看更多

查看更多

提问者
ddhille
被浏览
170
juunas 2020-02-01 00:12

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

至少应该在该函数实例上用作内存中的缓存。如果函数扩展到多个实例,则它们的缓存将被分离。