我正试图设置托管在Azure中的Web应用程序,以从Azure KeyVault读取设置。
我一直在遵循本指南:https://anthonychu.ca/post/secrets-aspnet-core-key-vault-msi/
该示例显示了如何使用以下配置从KeyVault访问应用设置:
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((ctx, builder) =>
{
var keyVaultEndpoint = Environment.GetEnvironmentVariable("KEYVAULT_ENDPOINT");
if (!string.IsNullOrEmpty(keyVaultEndpoint))
{
var azureServiceTokenProvider = new AzureServiceTokenProvider();
var keyVaultClient = new KeyVaultClient(
new KeyVaultClient.AuthenticationCallback(
azureServiceTokenProvider.KeyVaultTokenCallback));
builder.AddAzureKeyVault(
keyVaultEndpoint, keyVaultClient, new DefaultKeyVaultSecretManager());
}
})
.UseApplicationInsights()
.UseStartup<Startup>()
.Build();
我已经将KEYVAULT_ENDPOINT环境变量添加到了应用程序设置中。我已在应用程序服务上启用MSI,并已通过密钥保管库访问策略授权了我的Azure用户和应用程序:
具有获取和列出操作:
我已经将秘密添加到了密钥库中。在本地运行,我可以访问该机密。
但是我的ASP .NET Core网站在启动时失败,并在标准输出日志中显示以下内容:
Unhandled Exception: Microsoft.Azure.KeyVault.Models.KeyVaultErrorException: Operation returned an invalid status code 'Forbidden'
at Microsoft.Azure.KeyVault.KeyVaultClient.GetSecretsWithHttpMessagesAsync(String vaultBaseUrl, Nullable`1 maxresults, Dictionary`2 customHeaders, CancellationToken cancellationToken)
at Microsoft.Azure.KeyVault.KeyVaultClientExtensions.GetSecretsAsync(IKeyVaultClient operations, String vaultBaseUrl, Nullable`1 maxresults, CancellationToken cancellationToken)
at Microsoft.Extensions.Configuration.AzureKeyVault.AzureKeyVaultConfigurationProvider.LoadAsync()
at Microsoft.Extensions.Configuration.AzureKeyVault.AzureKeyVaultConfigurationProvider.Load()
at Microsoft.Extensions.Configuration.ConfigurationRoot..ctor(IList`1 providers)
at Microsoft.Extensions.Configuration.ConfigurationBuilder.Build()
at Microsoft.AspNetCore.Hosting.WebHostBuilder.BuildCommonServices(AggregateException& hostingStartupErrors)
at Microsoft.AspNetCore.Hosting.WebHostBuilder.Build()
at Blog.Program.BuildWebHost(String[] args) in D:\a\1\s\[csproj name]\Program.cs:line 22
at [csproj name].Program.Main(String[] args) in D:\a\1\s\[csproj name]\Program.cs:line 16
我已经通过从调试控制台调用SET来检查MSI_ENDPOINT和MSI_SECRET环境变量是否存在。
我还可以看到KEYVAULT_ENDPOINT变量。
任何建议可能出什么问题或下一步怎么做?由于它在本地工作,因此一定是身份验证问题,但是我认为它是使用我在密钥库中授权的Azure用户在本地进行身份验证,而不是作为Azure App Service在本地进行身份验证。
答案 0 :(得分:15)
这很狡猾,但是您设置的问题是,在为KeyValut创建访问策略时启用了“授权应用程序”。
您可以看到它,因为您的屏幕截图上有“ Application + Application”。我想,您创建的策略是Web应用程序既是主体应用程序又是经过授权的应用程序。这样会造成循环。
要使此设置生效,只需删除现有策略并创建一个新策略,即可在其中仅选择主体:
答案 1 :(得分:2)
要解决此问题,我必须将Web应用程序的IP地址添加到防火墙,因为当您选择“允许信任的Microsoft服务...”时,并不是全部添加了IP地址。
感谢:https://azidentity.azurewebsites.net/post/2019/01/03/key-vault-firewall-access-by-azure-app-services
答案 2 :(得分:1)
在AZ KV中,访问策略...只需选择主体即可。
答案 3 :(得分:1)
我想在这里添加另一个具有相同症状/错误消息的案例。当其中一个机密被禁用时,Azure 密钥保管库返回禁止。
我拥有所有必需的权限 - 我使用 Get 和 List 为我的应用服务的托管标识授予机密(我只使用机密)访问密钥库。
“访问被禁止”错误令人困惑,需要进行一些实验才能找出问题所在。希望这对遇到同样问题的人有所帮助。
答案 4 :(得分:0)
我以前见过这样的问题,开发和生产系统在处理环境变量时表现出不同的方式。
在这些情况下,我要看的第一部分是检查生产系统中是否正确地为环境变量添加了ASPNETCORE_
前缀。此前缀是ASP.NET Core Web主机的默认前缀。
| Key | Value |
|====================================|============================|
| ASPNETCORE_KEYVAULT_ENDPOINT | xxxxxxxxxxxxxxxx |
| ASPNETCORE_MSI_ENDPOINT** | xxxxxxxxxxxxxxxx |
| ASPNETCORE_MSI_SECRET** | xxxxxxxxxxxxxxxx |
**请注意,在您的代码中,我从未使用
MSI_ENDPOINT
或MSI_SECRET
看到您。我只看到您使用KEYVAULT_ENDPOINT
如果要显式设置前缀,则在通过配置初始化Web主机时,可以将要使用的前缀作为参数传递。
.AddEnvironmentVariables("ASPNETCORE_"); // choose your own prefix here
答案 5 :(得分:0)
答案 6 :(得分:0)
另一种可能是服务主体需要 Key Vault 的 API 权限。在 Azure 门户中,转到服务主体,然后在左侧菜单中选择 API 权限。然后单击添加权限。在这里您可以选择 Key Vault 并保存。这将允许代码检索密钥保管库机密。
答案 7 :(得分:0)
如果在通过 Visual Studio 登录 Azure 时添加了访问策略,则必须注销并重新登录以刷新权限。