如何通过一次调用 Azure 密钥保管库获取所有机密

问题描述 投票:0回答:6

我在这里使用示例代码解释

https://github.com/Azure-Samples/app-service-msi-keyvault-dotnet

但他们只解释了我们如何获得单个秘密而不是秘密列表。

所以为了获得所有秘密,我正在使用此代码示例

var all = kv.GetSecretsAsync(url).GetAwaiter().GetResult();
foreach (var secret in all)
{
    secretlist.Add(secret.Id);
}

但它只是获取秘密ID,而不是值。 我也想获得所有秘密的价值,所以有人可以帮助我如何做到这一点吗?

c# .net azure azure-keyvault
6个回答
12
投票

我们可以这样找到所有的钥匙

var secretClient = new SecretClient(new Uri($"https://{AzureKeyVaultName}.vault.azure.net/"), new DefaultAzureCredential());
var v = secretClient.GetPropertiesOfSecrets().AsPages().ToList();

11
投票

查看文档,

KeyVaultClient
Class不包含获取所有秘密(包括其值)的方法。
GetSecrets
方法“列出指定密钥保管库中的机密。”并返回一个包含类型为
SecretItem
的项目的列表,该列表不包含值,仅包含秘密元数据。

这与 Key Vault REST API 一致,其中有一个 GetSecrets 返回...您猜对了...SecretItems 列表。

长话短说:如果您想要所有秘密的所有值,则必须迭代列表并显式获取每个值。


7
投票

如果您使用较新的

Azure.Security.KeyVault.Secrets
包,那么您可以使用
GetPropertiesOfSecretsAsync
方法获取所有秘密,然后调用
GetSecretAsync
迭代每个结果。显然这仍然是 SELECT N+1 但目前似乎仍然没有其他方法可以做到这一点。

请注意,您需要使用 C# 8.0 才能使用此示例:

private SecretClient _client;

// ... setup your client, for example:

_client = new SecretClient("https://mykeyvault.vault.azure.net/", new DefaultAzureCredential());
        
// ...
        
public async Task<IList<KeyVaultSecret>> GetAllAsync(CancellationToken cancellationToken = default)
{
    AsyncPageable<SecretProperties> secretProperties = _client.GetPropertiesOfSecretsAsync(cancellationToken);

    var secrets = new List<KeyVaultSecret>();

    await foreach (var secretProperty in secretProperties)
    {
        var response = await _client.GetSecretAsync(secretProperty.Name, cancellationToken: cancellationToken).ConfigureAwait(false);
        
        secrets.Add(response.Value);
    }

    return secrets;
}

3
投票

您可以使用 listPropertiesOfSecrets 方法返回所有键。这样您就可以迭代并从保管库中获取所有秘密。


1
投票

你必须获取所有秘密,返回 SecretItem 的 IPage,然后迭代每个秘密以获取 SecretBundle,如下所示。这是我处理该操作的代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Azure.KeyVault;
using Microsoft.IdentityModel.Clients.ActiveDirectory;
using Newtonsoft.Json;

namespace TradingReplay.Engine
{
    public class SecurityCredentials : Serialisable<SecurityCredentials, SecurityCredentials>
    {
        public string VaultUrl { get; set; }
        public string ApplicationId {get; set;}
        private string ApplicationSecret { get; set; }
        internal Dictionary<string, string> Cache { get; set; } = new Dictionary<string, string>();

        public SecurityCredentials()
        { }

        public SecurityCredentials(string vaultUrl, string applicationId, string applicationSecret)
        {
            VaultUrl = vaultUrl;
            ApplicationId = applicationId;
            ApplicationSecret = applicationSecret;
        }

        public async Task<SecurityCredentials> InitialiseAzure()
        {
            var client = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(GetAccessTokenAsync), new HttpClient());
            var secrets = await client.GetSecretsAsync(VaultUrl);

            foreach (var item in secrets)
                Cache.Add(item.Identifier.Name, await GetSecretAsync(client, item.Identifier.Name));

            return this;
        }

        public async Task<string> GetSecretAsync(string key)
        {
            if (Cache.TryGetValue(key, out var value))
                return value;
            else
            {
                var client = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(GetAccessTokenAsync), new HttpClient());
                var secret = await GetSecretAsync(client, key);
                Cache.Add(key, secret);
                return secret;
            }
        }

        public async Task<string> GetSecretAsync(KeyVaultClient client, string key)
        {
            var secret = await client.GetSecretAsync(VaultUrl, key);
            return secret.Value;
        }

        private async Task<string> GetAccessTokenAsync(string authority, string resource, string scope)
        {
            var appCredentials = new ClientCredential(ApplicationId, ApplicationSecret);
            var context = new AuthenticationContext(authority, TokenCache.DefaultShared);

            var result = await context.AcquireTokenAsync(resource, appCredentials);

            return result.AccessToken;
        }
    }
}

出于测试目的,我注册了一个应用程序来访问我的 Azure 实例,并初始化该类,我所做的就是:

var credentials = await new SecurityCredentials("<vaultUrl>", "<applicationId>", "<applicationSecret>").InitialiseAzure();

然后可以拨打:

credentials["<secretName>"];

0
投票

使用Azure.Identity; 使用 Azure.Security.KeyVault.Secrets; 命名空间 key_vault_console_app { 班级计划 { 公共静态无效Main() { var kvUri = $"https://{您的 keyvault 名称}.vault.azure.net";

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

        var vishwa = client.GetPropertiesOfSecrets().AsPages().ToList();

        foreach (var kv in vishwa)
        {
            for (int i = 0; i < kv.Values.Count; i++)
            {
                Console.WriteLine($"Secret Name: {kv.Values[i].Name.ToString()}  ===> Secret Value:  {client.GetSecret(kv.Values[i].Name.ToString(), null).Value.Value}");
            }
        }
    }
}

}

© www.soinside.com 2019 - 2024. All rights reserved.