【发布时间】:2021-07-04 23:04:17
【问题描述】:
我正在使用 .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 将自动尝试链中的下一个凭据提供程序。就我而言,如果通过ManagedIdentityCredential 获取令牌失败,我希望代码自动尝试VisualStudioCredential。然而这并没有发生。
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),并在外部终端和 Visual Studio 内的终端中使用 az login 命令登录到 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] - SDK:
Azure.Identity (version 1.3.0)
问题
感谢您到目前为止的阅读(结果是一篇很长的帖子)。总而言之,这是我的问题:
- 在前 3 个案例中我做错了什么?
- 为什么
ChainedTokenCredential实现在ManagedIdentityCredential上失败,并且没有继续下一个?是不是对ChainedTokenCredential的实现有误解? - 为什么
VisualStudioCredential实现失败并出现not supported platform错误? - 为什么
AzureCliCredential实现失败并出现Azure CLI not installed错误,但它确实已安装并且我已登录。 - 最后,没有做任何特别的事情,为什么
DefaultAzureCredential实现有效?另外,它选择了哪些凭据?
对此的任何见解都将受到高度赞赏。
【问题讨论】:
标签: azure azure-active-directory azure-keyvault azure-identity