我正在使用.NET Core 2.1构建Web API。这将作为Azure Web App托管。我想将数据库连接字符串保留在我的Azure Key Vault中。这是我放入Startup.cs ConfigureServices方法中的代码:
services.AddDbContext<dbContext>(async options =>
{
var keyVaultUri = new Uri("https://xxxxxxxxx.vault.azure.net/");
var azureServiceTokenProvider = new AzureServiceTokenProvider();
var keyVaultClient = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(azureServiceTokenProvider.KeyVaultTokenCallback));
SecretBundle connectionStringSecret = await keyVaultClient.GetSecretAsync(keyVaultUri + "secrets/DBConnectionString");
options.UseSqlServer(connectionStringSecret.Value);
});
当我尝试向已注入dbContext的控制器进行HTTP Get操作时,出现以下错误:
InvalidOperationException: No database provider has been configured
for this DbContext. A provider can be configured by overriding the
DbContext.OnConfiguring method or by using AddDbContext on the
application service provider. If AddDbContext is used, then also
ensure that your DbContext type accepts a DbContextOptions<TContext>
object in its constructor and passes it to the base constructor for
DbContext.
我认为这是因为我使用了异步lambda来从Key Vault获取连接字符串,但是,我不确定该怎么做。这是从Azure KeyVault获取连接字符串以在Startup.cs中使用的正确方法吗?我应该以其他方式这样做吗?任何帮助,将不胜感激。谢谢。
答案 0 :(得分:3)
配置失败的原因是因为回调现在为async void
。
从lambda看,这并不明显,但实际上是开火而忘了。
当您等待密钥库客户端时,它会从回调中返回而无需配置提供程序。
对于解决方案,我认为最好将密钥库密钥添加到配置系统中,以便您可以从那里使用它们,就像它们是从JSON文件或任何其他来源传入的一样。
我前一段时间写了一篇文章:https://joonasw.net/view/aspnet-core-azure-keyvault-msi。 我在文章中使用托管身份进行身份验证,但我看到您也在使用它:)
以下是有关如何将Key Vault配置为ASP.NET Core 2.x中的配置源的示例:
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.ConfigureAppConfiguration((ctx, builder) =>
{
//Build the config from sources we have
var config = builder.Build();
//Add Key Vault to configuration pipeline
builder.AddAzureKeyVault(config["KeyVault:BaseUrl"]);
})
.Build();
本文中的示例实际上有点冗长,因为它将在内部使用AzureServiceTokenProvider来获取令牌。
您需要Microsoft.Extensions.Configuration.AzureKeyVault才能获得Key Vault的配置提供程序。
Key Vault中的秘密命名很重要。 例如,我们将覆盖以下连接字符串:
{
"ConnectionStrings": {
"DefaultConnection": "..."
}
}
您将必须创建一个名为 ConnectionStrings--DefaultConnection 的机密,并将连接字符串作为值。
然后在配置时仅使用Configuration["ConnectionStrings:DefaultConnection"]
来获取连接字符串。
如果添加了Key Vault配置并找到了具有正确名称的机密,它将来自Key Vault。