Azure Key Vault Quickstart 无法提供密钥保管库客户端

Azure Key Vault Quickstart fails to provide key vault client

我正在学习 Azure Key Vault。我正在尝试关注 https://docs.microsoft.com/en-us/azure/key-vault/secrets/quick-create-net。我在门户中创建了一个保险库,为用户帐户分配了访问策略。我在protal看到了vault,我看到用户已经设置了环境变量值。我在提示符下使用 'az login' 命令来使用该帐户。根据提示,我 运行 快速入门中的代码。它提示输入一个秘密。我输入 'bob.' 它抛出一个异常。

“正在 'mySecret' 中创建一个名为 'mySecret' 的秘密,其值为 'bob' ...未处理的异常。Azure.Identity.AuthenticationFailedException:SharedTokenCacheCredential 身份验证失败:A配置问题阻止身份验证 - 检查来自服务器的错误消息 details.You 可以在应用程序注册门户中修改配置。请参阅 https://aka.ms/msal-net-invalid-client for details. Original exception: AADSTS70002: The client does not exist or is not enabled for consumers. If you are the application developer, configure a new application through the App Registrations in the Azure Portal at https://go.microsoft.com/fwlink/?linkid=2083908."

异常在

await client.SetSecretAsync(secretName, secretValue);

我觉得问题出在

var client = new SecretClient(new Uri(kvUri), new DefaultAzureCredential());

客户端无法发送保管库接受的令牌。我很茫然。我有几个在使用 Vault 方面具有一定专业知识的人审查了这段代码,但他们无法提供见解。有帮助吗?

这是示例中的代码:

using System;
using System.Threading.Tasks;
using Azure.Identity;
using Azure.Security.KeyVault.Secrets;

namespace key_vault_console_app
{
    class Program
    {
        static async Task Main(string[] args)
        {
            const string secretName = "mySecret";
            var keyVaultName = Environment.GetEnvironmentVariable("KEY_VAULT_NAME");
            var kvUri = $"https://{keyVaultName}.vault.azure.net";

            var client = new SecretClient(new Uri(kvUri), new DefaultAzureCredential());

            Console.Write("Input the value of your secret > ");
            var secretValue = Console.ReadLine();

            Console.Write($"Creating a secret in {keyVaultName} called '{secretName}' with the value '{secretValue}' ...");
            await client.SetSecretAsync(secretName, secretValue);
            Console.WriteLine(" done.");

            Console.WriteLine("Forgetting your secret.");
            secretValue = string.Empty;
            Console.WriteLine($"Your secret is '{secretValue}'.");

            Console.WriteLine($"Retrieving your secret from {keyVaultName}.");
            var secret = await client.GetSecretAsync(secretName);
            Console.WriteLine($"Your secret is '{secret.Value}'.");

            Console.Write($"Deleting your secret from {keyVaultName} ...");
            DeleteSecretOperation operation = await client.StartDeleteSecretAsync(secretName);
            // You only need to wait for completion if you want to purge or recover the secret.
            await operation.WaitForCompletionAsync();
            Console.WriteLine(" done.");

            Console.Write($"Purging your secret from {keyVaultName} ...");
            await client.PurgeDeletedSecretAsync(secretName);
            Console.WriteLine(" done.");
        }
    }
}

不确定其根本原因。但是,如果您想使用用户帐户登录到 Azure 并访问您的密钥保管库,使用 UsernamePasswordCredential() 可能是一种解决方法。

要使用 UsernamePasswordCredential(),您应该在 Azure AD 中注册客户端应用程序:转到 Azure 门户 =>Azure Active Directory => 新注册

记下它的应用程序 ID:

转到 API 权限,并授予密钥保管库 user_impersonation 权限,以便用户可以通过此应用访问密钥保管库。 单击“Grant admin consent for..”以完成权限授予过程。

转到“身份验证”边栏选项卡,打开“允许 public 客户端流”,以便 Azure 将此应用视为 public 客户端:

尝试使用下面的代码创建一个秘密:

using System;
using System.Threading.Tasks;
using Azure.Identity;
using Azure.Security.KeyVault.Secrets;

namespace key_vault_console_app
{
    class Program
    {
        static async Task Main(string[] args)
        {
            const string secretName = "mySecret2";
            var keyVaultName = "<your kv name>";
            var kvUri = $"https://{keyVaultName}.vault.azure.net";

            var userCred = new UsernamePasswordCredential("<user account name>", "<user password>", "<your tenant name/id>", "<client application ID WHCIH we created above>");

            var client = new SecretClient(new Uri(kvUri), userCred);

            Console.Write("Input the value of your secret > ");
            var secretValue = Console.ReadLine();

            Console.Write($"Creating a secret in {keyVaultName} called '{secretName}' with the value '{secretValue}' ...");
            await client.SetSecretAsync(secretName, secretValue);
            Console.WriteLine(" done.");

        }
    }
}

结果: