Azure.Security.KeyVault.Secrets中的Azure.RequestFailedException
我开发了一个在 Azure 虚拟机规模集中运行的服务,该服务从 Azure Key Vault 访问配置。最近在调试这个服务的RequestFailedException时候,访问配置的时候就开始收到了。
在 Azure 中,Key Vault 通过具有适当权限的用户分配的托管标识进行访问。该服务目前在 Azure 中运行良好,但我无法在本地调试。我在 Visual Studio 2019 版本 16.8.6 的 Azure 服务身份验证配置部分选择了我的 Azure 帐户,并且该帐户具有对 Key Vault 的权限(配置为允许从所有网络访问)。
这是一个片段,显示了我如何在.NET Core 3.1平台上使用Azure Identity 1.2.2和Azure.Security.KeyVault.Secrets 4.1.0访问密钥保管库:
private const string KeyVault = "https://<key vault name>.vault.azure.net/";
var client = new SecretClient(new Uri(KeyVault), new DefaultAzureCredential());
var secret = client.GetSecret("<name of secret in key vault>");
显然DefaultAzureCredential使用VisualStudioCredential来解决访问,但是这在某种程度上被 Visual Studio 的更新(自我上次成功调试会话以来唯一更改的)或可能来自 Azure Key Vault 的策略更改所破坏。
完全例外
Exception thrown: 'Azure.RequestFailedException' in Azure.Security.KeyVault.Secrets.dll
An unhandled exception of type 'Azure.RequestFailedException' occurred in Azure.Security.KeyVault.Secrets.dll
Service request failed.
Status: 403 (Forbidden)
Content:
{"error":{"code":"Forbidden","message":"Access denied to first party service.rnCaller: name=from-infra;tid=<redacted>;appid=<redacted>;iss=https://sts.windows.net/<appid>/rnVault: <key vault name>;location=australiaeast","innererror":{"code":"AccessDenied"}}}
升级图书馆
我将Azure.Identity库升级到版本1.3.0。这产生了更详细的异常:
Microsoft.Extensions.Configuration.AzureAppConfiguration.KeyVaultReferenceException: SharedTokenCacheCredential authentication failed: AADSTS9002332: Application 'cfa8b339-82a2-471a-a3c9-0fc0be7a4093'(Azure Key Vault) is configured for use by Azure Active Directory users only.
此问题中描述了完整的例外情况。似乎DefaultAzureCredential正在尝试使用SharedTokenCacheCredential. 我更新了我的代码以明确禁用共享令牌缓存凭据:
Exception thrown: 'Azure.RequestFailedException' in Azure.Security.KeyVault.Secrets.dll
An unhandled exception of type 'Azure.RequestFailedException' occurred in Azure.Security.KeyVault.Secrets.dll
Service request failed.
Status: 403 (Forbidden)
Content:
{"error":{"code":"Forbidden","message":"Access denied to first party service.rnCaller: name=from-infra;tid=<redacted>;appid=<redacted>;iss=https://sts.windows.net/<appid>/rnVault: <key vault name>;location=australiaeast","innererror":{"code":"AccessDenied"}}}
然而,这会产生如上所述的原始异常。链接问题的已接受答案将租户 ID、客户端 ID 和用户机密编码到应用程序中,我不愿意这样做。示例文档使用备用库Microsoft.Azure.Services.AppAuthentication和Microsoft.Azure.KeyVault。
我的服务在 Azure 中运行良好。我想在本地调试它,就像几个月前一样。有什么我可以做的吗?
回答
要在不使用硬编码机密的情况下解决此问题,请禁用 Visual Studio 身份验证凭据并使用备用身份验证方法。
就我而言,我使用了AzureCliCredential. 首先,我使用有权访问 Key Vault 的帐户(在 Visual Studio 的“Azure 服务身份验证”配置中选择的帐户相同)在我的开发环境中登录 Azure:
az login
az login
然后我的代码更新要么使用DefaultAzureCredential与VisualStudioCredential禁用,或使用ChainedTokenCredential选择适当的方法:
或者:
var options = new DefaultAzureCredentialOptions { ExcludeVisualStudioCredential = true };
var client = new SecretClient(new Uri(KeyVault), new DefaultAzureCredential(options));
我相信这是 Visual Studio 的一个错误,并且已经记录了一个问题。