我正在使用 .Net 5 构建 Web API。Web API 受 Azure AD 保护,可由单个租户访问。Web API 将连接到其他 Azure 资源(存储、Cosmos DB 等),这些资源的连接字符串作为机密存储在 Azure Key Vault 中。
我的目标是在 API 启动时从 Azure Key Vault 获取这些连接字符串(秘密),并使用它们连接到这些资源。当 Web API 部署到生产环境时,它将managed identity用于连接到 Key Vault 并获取机密。在开发过程中,我想使用其他一些机制来连接并获取秘密。我不想为此创建Service Principal和使用客户端 ID/客户端密码。
我想知道在开发过程中如何实现连接,那时我发现了获取令牌的不同机制。但是,当我使用它们时,我遇到了许多问题,现在我对使用它们感到困惑。
1. ChainedTokenCredential
在研究的过程中,我遇到了Secretless Development from Local to Cloud with the New Azure SDKs, Project Tye, and Kubernetes视频,随后memealyzer在我了解的地方进行了项目ChainedTokenCredential。根据我的理解,您可以链接多个令牌凭据,SDK 将尝试连接到每个令牌凭据,直到成功。这对我来说听起来很完美,我最终实现了类似于下面的代码:
ChainedTokenCredential chainedTokenCredential = new ChainedTokenCredential(
new ManagedIdentityCredential(),
new VisualStudioCredential()
);
SecretClient client = new SecretClient(new Uri("https://mykv.vault.azure.net"), chainedTokenCredential);
KeyVaultSecret secret = await secretClient.GetSecretAsync("mysecretkeyname");
根据我的理解,如果我在 Visual Studio 中运行上面的代码,代码应该首先尝试使用ManagedIdentityCredential()(这将失败)然后VisualStudioCredential()(这应该成功,因为我使用有权访问的帐户登录到 Visual Studio Key Vault 机密。
然而令我惊讶的是,代码引发了以下异常:
Azure.Identity.CredentialUnavailableException: The ChainedTokenCredential failed to retrieve a token from the included credentials.
- ManagedIdentityCredential authentication unavailable. No Managed Identity endpoint found.
当我在本地运行代码时,异常是有意义的。但是,据我了解,如果出现异常,SDK 将自动尝试链中的下一个凭据提供程序。就我而言,如果通过失败VisualStudioCredential获取令牌,我希望代码自动尝试。ManagedIdentityCredential然而,这并没有发生。
2.VisualStudioCredential
接下来,我注释掉ManagedIdentityCredential()并只是VisualStudioCredential认为考虑到我使用正确的凭据登录到 Visual Studio,它会起作用。

ChainedTokenCredential chainedTokenCredential = new ChainedTokenCredential(
//new ManagedIdentityCredential(),
new VisualStudioCredential()
);
SecretClient client = new SecretClient(new Uri("https://mykv.vault.azure.net"), chainedTokenCredential);
KeyVaultSecret secret = await secretClient.GetSecretAsync("mysecretkeyname");
但是,这也因以下错误而失败:
Azure.Identity.CredentialUnavailableException: Operating system Darwin 20.3.0 Darwin Kernel Version 20.3.0: Thu Jan 21 00:06:51 PST 2021; root:xnu-7195.81.3~1/RELEASE_ARM64_T8101 isn't supported.
3. AzureCliCredential
莫名其妙,我换VisualStudioCredential了AzureCliCredential又试了。我已经安装了最新版本的 Azure CLI (2.21.0),并az login在外部终端和 Visual Studio 内的终端中使用命令登录到 Azure CLI。

ChainedTokenCredential chainedTokenCredential = new ChainedTokenCredential(
//new ManagedIdentityCredential(),
new AzureCliCredential()
);
SecretClient client = new SecretClient(new Uri("https://mykv.vault.azure.net"), chainedTokenCredential);
KeyVaultSecret secret = await secretClient.GetSecretAsync("mysecretkeyname");
但是,这也因以下错误而失败:
Azure.Identity.CredentialUnavailableException: Azure CLI not installed
考虑到安装了 Azure CLI 并且我在那里登录,这没有任何意义。
4. 默认AzureCredential
极度困惑和沮丧,我最终决定使用DefaultAzureCredential认为这是我最后的手段。但是我没有在 Azure AD 等中创建任何应用程序注册,只是执行了以下代码:
SecretClient client = new SecretClient(new Uri(keyVaultConfiguration.VaultUri), new DefaultAzureCredential());
KeyVaultSecret secret = await secretClient.GetSecretAsync("mysecretkeyname");
现在在这里,我期待代码失败,但令我惊讶的是,代码有效(我猜是 Azure Identity 的奥秘 :))并且我能够获得秘密。我想知道为什么上面的代码有效以及它选择了哪个令牌凭据(考虑到我都使用相同的凭据登录到 Visual Studio 和 Azure CLI)。
开发环境
- IDE:
Visual Studio version 8.9.4 (build 25) - 操作系统:
macOS Big Sur (11.2.3) [Apple Silicon] - 开发工具包:
Azure.Identity (version 1.3.0)
问题
感谢您到目前为止的阅读(结果是一篇很长的帖子)。总而言之,这是我的问题:
- 在前 3 个案例中我做错了什么?
- 为什么
ChainedTokenCredential执行失败ManagedIdentityCredential并且没有继续下一个?我误解了 的实施ChainedTokenCredential吗? - 为什么
VisualStudioCredential执行失败并not supported platform出现错误? - 为什么在确定安装并且我已登录时
AzureCliCredential执行失败并出现错误。Azure CLI not installed - 最后,没有做任何特别的事情,为什么
DefaultAzureCredential实施有效?另外,它选择了哪些凭据?
对此的任何见解都将受到高度赞赏。