[英]Best approach to load Azure Secrets in a .NET application
I'm trying to find the best solution to reload Azure Secrets in a .NET 5 application.我正在尝试寻找在 .NET 5 应用程序中重新加载 Azure Secrets 的最佳解决方案。 I will write here what I have now.我会把我现在所拥有的写在这里。
First I did this:首先我这样做:
.ConfigureAppConfiguration((context, configuration) =>
{
var configurationRoot = configuration.Build();
config.AddAzureKeyVault(
new Uri(configurationRoot["KeyVault:Uri"]),
new DefaultAzureCredential()
});
But, there is a problem.但有个问题。 Secrets are cached until IConfigurationRoot.Reload()
is called.秘密被缓存,直到IConfigurationRoot.Reload()
被调用。 Expired, disabled, and updated secrets in the key vault aren't respected by the app until Reload is executed or if ReloadInterval
is used as an option in AddAzureKeyVault
.过期,禁用,并在关键金库更新的秘密,直到执行刷新不被尊重的应用程序,或者如果ReloadInterval
被用作一个选项AddAzureKeyVault
。
My second approach was to add an interval to reload the secrets automatically every 15 minutes.我的第二种方法是添加一个间隔,每 15 分钟自动重新加载机密。 (And use IOptionsSnapshot
instead of IOptions
to get the most recent values) (并使用IOptionsSnapshot
而不是IOptions
来获取最新值)
.ConfigureAppConfiguration((context, configuration) =>
{
var configurationRoot = configuration.Build();
int reloadInterval;
bool success = int.TryParse(configurationRoot["KeyVault:ReloadInterval"], out reloadInterval);
config.AddAzureKeyVault(
new Uri(configurationRoot["KeyVault:Uri"]),
new DefaultAzureCredential(),
new AzureKeyVaultConfigurationOptions()
{
ReloadInterval = TimeSpan.FromMinutes(success ? reloadInterval : 15)
});
});
I still think that is not the best solution, because there is still a time window (in this example 15 minutes) in which the secrets in Azure can be changed and if I try to use them I will not have the latest version.我仍然认为这不是最好的解决方案,因为还有一个时间窗口(在本例中为 15 分钟),可以在其中更改 Azure 中的机密,如果我尝试使用它们,我将不会获得最新版本。
So, I tried a solution where I manually call IConfigurationRoot.Reload()
when I have an error about an invalid secret.因此,我尝试了一个解决方案,当我遇到有关无效秘密的错误时,我手动调用IConfigurationRoot.Reload()
。 For example in MongoDbContext
, if the connection string is invalid I will get a MongoConfigurationException
.例如在MongoDbContext
,如果连接字符串无效,我将收到MongoConfigurationException
。
Using Polly
I did this:使用Polly
我这样做了:
public MongoDbContext(IOptionsSnapshot<DatabaseSettings> databaseSettings, ILogger<MongoDbContext> logger)
{
_logger = logger;
_databaseSettings = databaseSettings.Value;
_policy = Policy
.Handle<MongoConfigurationException>()
.Retry(1, (exception, retryCount) =>
{
// Reload configuration
});
_policy.Execute(() => _mongoClient = new MongoClient(_databaseSettings.ConnectionString));
_mongoDatabase = _mongoClient.GetDatabase(_databaseSettings.DatabaseName);
}
Or maybe this one is better:或者也许这个更好:
{
_logger = logger;
_databaseSettings = databaseSettings.Value;
_circuitBreakerPolicy = Policy
.Handle<MongoConfigurationException>()
.CircuitBreaker(1, TimeSpan.FromSeconds(10));
_retryPolicy = Policy.Handle<MongoConfigurationException>()
.Retry(1, (exception, retryCount) =>
{
// Reload configuration
});
_policy = Policy.Wrap(_retryPolicy, _circuitBreakerPolicy);
_policy.Execute(() => _mongoClient = new MongoClient(_databaseSettings.ConnectionString));
_mongoDatabase = _mongoClient.GetDatabase(_databaseSettings.DatabaseName);
}
But, with this approach it means that I should do the same thing and catch that specific exception everywhere in the application where I use a secret.但是,使用这种方法意味着我应该做同样的事情并在应用程序中使用秘密的任何地方捕获该特定异常。 Also, I wasn't yet able to inject IConfigurationRoot
in this class and I don't know if is OK to do that.另外,我还不能在这个类中注入IConfigurationRoot
,我不知道这样做是否可以。 MongoDbContext
is part of the Infrastructure project outside the WebApi project. MongoDbContext
是MongoDbContext
项目之外的基础设施项目的一部分。
Use Azure.Extensions.AspNetCore.Configuration.Secrets to load the Azure secrets in .NET application使用Azure.Extensions.AspNetCore.Configuration.Secrets在 .NET 应用程序中加载 Azure 机密
An overload of AddAzureKeyVault
that takes an AzureKeyVaultConfigurationOptions
parameter and allows specifying the reload interval. AddAzureKeyVault
的重载,它采用AzureKeyVaultConfigurationOptions
参数并允许指定重新加载间隔。
configurationBuilder.AddAzureKeyVault(new AzureKeyVaultConfigurationOptions
{
Vault = configuration["KeyVaultUrl"],
ReloadInterval = TimeSpan.FromMinutes(10),
});
OR you may try with this或者你可以试试这个
Update the AddAzureAppConfiguration
method to set up a refresh interval for your Key Vault certificate using the SetSecretRefreshInterval
method.更新AddAzureAppConfiguration
方法以使用SetSecretRefreshInterval
方法为 Key Vault 证书设置刷新间隔。 With this change, your application will reload the public-private key pair for ExampleCertificate every 12 hours.通过此更改,您的应用程序将每 12 小时重新加载 ExampleCertificate 的公私密钥对。
config.AddAzureAppConfiguration(options =>
{
options.Connect(settings["ConnectionStrings:AppConfig"])
.ConfigureKeyVault(kv =>
{
kv.SetCredential(new DefaultAzureCredential());
kv.SetSecretRefreshInterval("TestApp:Settings:KeyVaultCertificate", TimeSpan.FromHours(12));
});
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.