繁体   English   中英

在 .NET 应用程序中加载 Azure Secrets 的最佳方法

[英]Best approach to load Azure Secrets in a .NET application

我正在尝试寻找在 .NET 5 应用程序中重新加载 Azure Secrets 的最佳解决方案。 我会把我现在所拥有的写在这里。
首先我这样做:

.ConfigureAppConfiguration((context, configuration) =>
{
    var configurationRoot = configuration.Build();

    config.AddAzureKeyVault(
        new Uri(configurationRoot["KeyVault:Uri"]),
        new DefaultAzureCredential()
});

但有个问题。 秘密被缓存,直到IConfigurationRoot.Reload()被调用。 过期,禁用,并在关键金库更新的秘密,直到执行刷新不被尊重的应用程序,或者如果ReloadInterval被用作一个选项AddAzureKeyVault

我的第二种方法是添加一个间隔,每 15 分钟自动重新加载机密。 (并使用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)
        });
});

我仍然认为这不是最好的解决方案,因为还有一个时间窗口(在本例中为 15 分钟),可以在其中更改 Azure 中的机密,如果我尝试使用它们,我将不会获得最新版本。
因此,我尝试了一个解决方案,当我遇到有关无效秘密的错误时,我手动调用IConfigurationRoot.Reload() 例如在MongoDbContext ,如果连接字符串无效,我将收到MongoConfigurationException
使用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);
}

或者也许这个更好:

{
    _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);
}

但是,使用这种方法意味着我应该做同样的事情并在应用程序中使用秘密的任何地方捕获该特定异常。 另外,我还不能在这个类中注入IConfigurationRoot ,我不知道这样做是否可以。 MongoDbContextMongoDbContext项目之外的基础设施项目的一部分。

使用Azure.Extensions.AspNetCore.Configuration.Secrets在 .NET 应用程序中加载 Azure 机密

AddAzureKeyVault的重载,它采用AzureKeyVaultConfigurationOptions参数并允许指定重新加载间隔。

configurationBuilder.AddAzureKeyVault(new AzureKeyVaultConfigurationOptions 
{ 
    Vault = configuration["KeyVaultUrl"], 
    ReloadInterval = TimeSpan.FromMinutes(10), 
}); 

或者你可以试试这个

更新AddAzureAppConfiguration方法以使用SetSecretRefreshInterval方法为 Key Vault 证书设置刷新间隔。 通过此更改,您的应用程序将每 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM