在 Azure 函数中缓存 public JWT 身份验证密钥
Caching public JWT authentication keys in Azure Function
我有一个带有各种端点的 Azure 函数 .NET 核心 2.1。
对于身份验证,我有一个外部安全提供程序,我需要从那里检索发现文档(元数据),然后才能验证请求的令牌。
当前每次发出单个请求时都会加载文档:
var discoveryDocument = await configurationManager.GetConfigurationAsync();
现在我自然不想对每个请求都进行此调用,因为文档很少更改。
另一方面,Azure 函数是无状态的。我听说 ConfigurationManager.GetConfigurationAsync()
正在以某种方式缓存检索到的数据,但我找不到这方面的更多信息。目前,我最终得到了一个在启动时触发一次的函数,检索文档并将其存储在本地文件系统中。因此,当发出请求时,我会再次读取文件,以避免再次请求获取 public 键。
有这方面的经验吗?
解决方案:
我可以按照@juunas 的建议用静态 class 解决它。
对于每个函数,我都重新使用 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;
}
}
}
您可以将数据存储在静态字段中(也可以在单独的静态字段中 class)。
至少应该作为该函数实例的内存缓存。
如果函数扩展到多个实例,它们的缓存将被分开。
我有一个带有各种端点的 Azure 函数 .NET 核心 2.1。
对于身份验证,我有一个外部安全提供程序,我需要从那里检索发现文档(元数据),然后才能验证请求的令牌。
当前每次发出单个请求时都会加载文档:
var discoveryDocument = await configurationManager.GetConfigurationAsync();
现在我自然不想对每个请求都进行此调用,因为文档很少更改。
另一方面,Azure 函数是无状态的。我听说 ConfigurationManager.GetConfigurationAsync()
正在以某种方式缓存检索到的数据,但我找不到这方面的更多信息。目前,我最终得到了一个在启动时触发一次的函数,检索文档并将其存储在本地文件系统中。因此,当发出请求时,我会再次读取文件,以避免再次请求获取 public 键。
有这方面的经验吗?
解决方案:
我可以按照@juunas 的建议用静态 class 解决它。
对于每个函数,我都重新使用 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;
}
}
}
您可以将数据存储在静态字段中(也可以在单独的静态字段中 class)。
至少应该作为该函数实例的内存缓存。 如果函数扩展到多个实例,它们的缓存将被分开。