用于 DBContext 的 Azure KeyVault:"No database provider has been configured for this DbContext"
Azure KeyVault for DBContext: "No database provider has been configured for this DbContext"
我正在使用 .NET Core 2.1 构建 Web API。这将作为 Azure Web 应用程序托管。我想将我的数据库连接字符串保存在我的 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 的正确方法吗?我应该以不同的方式做到这一点吗?任何帮助,将不胜感激。谢谢
您的配置失败的原因是回调现在是 async void
。
从 lambda 上看这并不明显,但它实际上是即发即忘。
当您等待 Key Vault 客户端时,它 returns 来自回调而不配置提供者。
至于解决方案,我认为最好将密钥保管库机密添加到配置系统中,这样您就可以从那里使用它们,就好像它们来自 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。
我正在使用 .NET Core 2.1 构建 Web API。这将作为 Azure Web 应用程序托管。我想将我的数据库连接字符串保存在我的 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 的正确方法吗?我应该以不同的方式做到这一点吗?任何帮助,将不胜感激。谢谢
您的配置失败的原因是回调现在是 async void
。
从 lambda 上看这并不明显,但它实际上是即发即忘。
当您等待 Key Vault 客户端时,它 returns 来自回调而不配置提供者。
至于解决方案,我认为最好将密钥保管库机密添加到配置系统中,这样您就可以从那里使用它们,就好像它们来自 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。