我正在使用 .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
实施有效?另外,它选择了哪些凭据?
对此的任何见解都将受到高度赞赏。