如何在一次呼叫Azure密钥保管库中获取所有机密

时间:2018-11-27 12:10:22

标签: c# .net azure azure-keyvault

我正在使用示例代码在此处进行解释

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,而不是值。 我也想获得所有秘密的价值,所以任何人都可以帮助我做到这一点吗?

4 个答案:

答案 0 :(得分:3)

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

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

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

答案 1 :(得分:0)

您必须获取所有机密,返回一个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>"];

答案 2 :(得分:0)

如果使用的是较新的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(name, cancellationToken: cancellationToken).ConfigureAwait(false);
        
        secrets.Add(response.Value);
    }

    return secrets;
}

答案 3 :(得分:0)

您可以使用返回所有密钥的 listPropertiesOfSecrets 方法。通过这种方式,您可以迭代并从保险库中获取所有机密。