使用服务标识时无法连接到 Azure Key Vault

Dan*_*nez 6 asp.net azure azure-keyvault

我正在尝试使用 ASPNet 4.6.2 Web 应用程序中的服务标识从 Azure Key Vault 检索机密。我正在使用本文中概述的代码。在本地,一切正常,尽管这是因为它使用了我的身份。当我将应用程序部署到 Azure 时keyVaultClient.GetSecretAsync(keyUrl),调用时出现异常。

尽我所知,一切都配置正确。我创建了一个用户分配的身份,以便可以重复使用,并确保该身份可以访问 KeyVault 策略中的机密和密钥。

一个例外是AzureServiceTokenProviderException. 它很冗长,并概述了它如何尝试四种方法来进行身份验证。我关心的信息是它何时尝试使用托管服务标识:

尝试使用托管服务标识获取令牌。无法获取访问令牌。MSI 响应代码:BadRequest,响应:

我检查了应用程序见解,发现它试图与 400 结果错误建立以下连接:

http://127.0.0.1:41340/MSI/token/?resource=https://vault.azure.net&api-version=2017-09-01
Run Code Online (Sandbox Code Playgroud)

这有两件有趣的事情:

  1. 为什么要尝试连接到本地主机地址?这似乎是错误的。
  2. 因为资源参数没有转义,这会得到 400 吗?
  3. 在 MsiAccessTokenProvider源中,它仅在设置了环境变量 MSI_ENDPOINT 和 MSI_SECRET 时才使用该地址形式。它们没有在应用程序设置中设置,但是当我输出环境变量时,我可以在调试控制台中看到它们。

此时我不知道该怎么办。网上的例子都让它看起来很神奇,但如果我对问题的根源是正确的,那么有一些模糊的自动化设置需要修复。

为了完整起见,这里是我所有的相关代码:

public class ServiceIdentityKeyVaultUtil : IDisposable
{
    private readonly AzureServiceTokenProvider azureServiceTokenProvider;
    private readonly Uri baseSecretsUri;
    private readonly KeyVaultClient keyVaultClient;


    public ServiceIdentityKeyVaultUtil(string baseKeyVaultUrl)
    {
        baseSecretsUri = new Uri(new Uri(baseKeyVaultUrl, UriKind.Absolute), "secrets/");
        azureServiceTokenProvider = new AzureServiceTokenProvider();
        keyVaultClient = new KeyVaultClient(
            new KeyVaultClient.AuthenticationCallback(azureServiceTokenProvider.KeyVaultTokenCallback));
    }

    public async Task<string> GetSecretAsync(string key, CancellationToken cancellationToken = new CancellationToken())
    {
        var keyUrl = new Uri(baseSecretsUri, key).ToString();
        try
        {
            var secret = await keyVaultClient.GetSecretAsync(keyUrl, cancellationToken);
            return secret.Value;
        }
        catch (Exception ex)
        {
            /** rethrows error with extra details */
        }
    }

    /** IDisposable support */
}
Run Code Online (Sandbox Code Playgroud)

更新 #2 (我删除了更新 #1)

我创建了一个全新的应用程序或一个新的服务实例,并且能够重新创建错误。 但是,在所有情况下,我都使用用户分配的身份。如果我删除它并使用系统分配的身份,那么它就可以正常工作。

我不知道为什么这些会有所不同。任何人都有洞察力,因为我更喜欢分配给用户的洞察力。

Mur*_*oft 1

用户分配身份的主要区别之一是您可以将其分配给多个服务。它在 azure 中作为单独的资产存在,而系统身份则绑定到与其配对的服务的生命周期。

来自文档

系统分配的托管标识直接在 Azure 服务实例上启用。启用标识后,Azure 会在实例订阅信任的 Azure AD 租户中为实例创建一个标识。创建身份后,将凭证配置到实例上。系统分配标识的生命周期直接与其启用的 Azure 服务实例相关联。如果实例被删除,Azure 会自动清理 Azure AD 中的凭据和标识。

用户分配的托管标识作为独立的 Azure 资源创建。通过创建过程,Azure 在 Azure AD 租户中创建一个受正在使用的订阅信任的身份。创建身份后,可以将该身份分配给一个或多个 Azure 服务实例。用户分配的标识的生命周期与其所分配到的 Azure 服务实例的生命周期分开管理。

用户分配的身份仍处于应用服务预览状态。请参阅此处的文档。它可能仍处于私人预览版(即 Microsoft 必须在您的订阅中明确启用它),它可能在您选择的区域中不可用,或者可能是一个缺陷。

在此输入图像描述