在“我得到它的工作”下提交这个答案,但我欢迎 cmets 提供更好的方法来使用 Azure Key Vault 机密,特别是因为我发现的在线示例不一致。
首先,我使用的是 Visual Studio 2019。它具有如下所述的开发身份验证设置:
Service-to-service authentication to Azure Key Vault using .NET
有很多方法可以进行身份验证。我只尝试过 Visual Studio 技术,但是一旦你开始使用它,就不应该很难弄清楚如何使用其他方法。即使我在生产环境的代码中有保护,我也没有在生产环境中尝试过下面的代码。我只是颠倒了逻辑以在我的开发环境中测试密钥库。话虽如此,这就是我所做的:
安装这些 NuGet 包:
- Azure.Identity
- Microsoft.Azure.KeyVault
注意:上面的链接表明这个包已经过时了,即使它在同一篇文章中被提及:
- Microsoft.Azure.Services.AppAuthentication
所以不要安装它。
在我的 web api .Net Core 3.1 应用程序中,Program 类代码有额外的 ConfigureAppConfiguration() 调用:
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((ctx, builder) =>
{
if (ctx.HostingEnvironment.IsProduction())
{
var config = builder.Build();
var tokenProvider = new AzureServiceTokenProvider();
var kvClient = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(tokenProvider.KeyVaultTokenCallback));
builder.AddAzureKeyVault(config["KeyVault:BaseUrl"], kvClient, new DefaultKeyVaultSecretManager());
}
})
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
}
注意:如果您想在开发中测试而不是使用 secrets.json 设置,请更改此行:
if (ctx.HostingEnvironment.IsProduction())
到
if (!ctx.HostingEnvironment.IsProduction())
旁注:在 Visual Studio 中,右键单击您的项目并单击“管理用户机密”或使用 dotnet CLI user-secrets 命令来管理它们。 Key Vault 设置将覆盖 secrets.json 设置。
我的 appsettings.json 文件有这个部分:
"KeyVault": {
"BaseUrl": "https://mykeyvaultname.vault.azure.net/",
"Secrets": {
"Secret1": "foo",
"Secret2": "bar"
}
},
注意 program.cs 中的这一行与 KeyVault 部分位置匹配:
builder.AddAzureKeyVault(config["KeyVault:BaseUrl"], kvClient, new DefaultKeyVaultSecretManager());
阅读有关 Key Vault 的本教程以了解如何设置机密:
Tutorial: Use Key Vault references in an ASP.NET Core app
我创建了两个类来匹配两种不同的配置。第一个仅匹配密钥保管库中的机密。第二个匹配他们的密钥保管库和 appsettings 文件,但密钥保管库机密优先:
这个类只匹配我的密钥库中的两个秘密,“MySecretKey 和”MyOtherSecretKey”
public class KeyVaultSettingsModel
{
public string MyOtherSecretKey { get; set; }
public string MySecretKey { get; set; }
}
以及与 appsettings.json 文件中的“KeyVault:Secrets”路径匹配的另一个类:
public class KeyVaultSettingsModel1
{
public string Secret1 { get; set; }
public string Secret2 { get; set; }
}
如果您在 appsettings 文件中有嵌套值,则密钥保管库中的密钥名称必须与之匹配。但是您必须将“:”字符替换为“--”。这意味着您的秘密名称必须采用以下形式:
KeyVault--Secrets--Secret1
不是
KeyVault:Secrets:Secret1
完成上述配置后,您可以使用选项模式。在 Startup.cs 中,将您的模型配置为与 IOptions* 接口一起使用,并在需要时使用 DI 访问它们。
public void ConfigureServices(IServiceCollection services)
{
// other code
services.Configure<KeyVaultSettingsModel>(Configuration);
services.Configure<KeyVaultSettingsModel1>(Configuration.GetSection("KeyVault:Secrets"));
// other code
}