我有一个具有各种终结点的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;
}
}
}
您可以将数据存储在静态字段中(也可以在单独的静态类中)。
至少应该在该函数实例上用作内存中的缓存。如果函数扩展到多个实例,则它们的缓存将被分离。