如何向 Azure C# SecretClient 提供凭据 (DefaultAzureCredential)?它似乎忽略了凭据和 RBAC 并抛出 403

How to give credentials (DefaultAzureCredential) to Azure C# SecretClient? It seems to ignore credentials and RBAC and throw 403

我有一个带有密钥保管库的 Azure Web 应用程序。我想使用 C# 应用程序将机密存储在密钥保管库中。

我的 C# 应用程序可以将机密上传到开发,但不能上传到生产,无论我提供什么凭据。在生产中它总是抛出以下错误:

Azure.RequestFailedException: Service request failed.
Status: 403 (Forbidden)

Content:
{"error":{"code":"Forbidden","message":
    "Caller is not authorized to perform action on resource.\r\n
     If role assignments, deny assignments or role definitions were changed recently, please observe propagation time.\r\n
     Caller: appid=<GUID>;oid=<GUID>;iss=https://sts.windows.net/<GUID>/\r\n
     Action: 'Microsoft.KeyVault/vaults/secrets/setSecret/action'\r\n
     Resource: '<path to my secret>'\r\n
     Assignment: (not found)\r\n
     Vault: <name>;location=westeurope\r\n",
    "innererror":{"code":"ForbiddenByRbac"}}}

错误消息说它与RBAC有关。我不明白它从哪里获得权利。我正在从 PowerShell 提示符调用应用程序。我以为它会从 PowerShell 获取我的权限,但我做 az loginaz logoutaz account set 都没有区别。无论我做什么,它都可以很好地上传到开发,但不能上传到生产。

我用的是classAzure.Security.KeyVault.Secrets.SecretClient。我是这样创建的:

private SecretClient CreateSecretClient() =>
    new(
        new Uri($"https://{_keyVaultName}.vault.azure.net/"),
        new DefaultAzureCredential(),
        new SecretClientOptions
        {
            Retry =
            {
                Delay = TimeSpan.FromSeconds(2),
                MaxDelay = TimeSpan.FromSeconds(16),
                MaxRetries = 5,
                Mode = RetryMode.Exponential
            }
        });

我是这样写秘籍的:

var keyVaultSecret = new KeyVaultSecret(secretName, value);
await _secretClient.SetSecretAsync(keyVaultSecret, ct);

我也试过给它一个托管身份(它应该有权访问生产而不是开发):

new DefaultAzureCredential(
    new DefaultAzureCredentialOptions
    {
        ManagedIdentityClientId = <GUID>
    })

还是一样的结果。它愿意写给开发,而不是生产。我什至试图给它一个 ManagedIdentityClientId ,这是胡说八道,不指向任何现有的托管身份。结果相同。

在我看来,我的 SecretClient 似乎忽略了其分配的凭据对象和 PowerShell 会话中的权限。它会凭空变出它的权限吗?无论我做什么,它如何能够写入我的开发环境?我如何让它访问我的其他环境?

我找到了一个有效的修复方法。我可以使用 InteractiveBrowserCredential 而不是 DefaultAzureCredential.

    private SecretClient CreateSecretClient() =>
        new(
            new Uri($"https://{_keyVaultName}.vault.azure.net/"),
            new InteractiveBrowserCredential(),
            new SecretClientOptions
            {
                Retry =
                {
                    Delay = TimeSpan.FromSeconds(2),
                    MaxDelay = TimeSpan.FromSeconds(16),
                    MaxRetries = 5,
                    Mode = RetryMode.Exponential
                }
            });

我可能还可以使用其他类型的 TokenCredential,如下所列:https://docs.microsoft.com/en-us/dotnet/api/azure.identity.defaultazurecredential?view=azure-dotnet