【问题标题】:How to get all secrets in one call Azure key vault如何在一次调用 Azure 密钥保管库中获取所有机密
【发布时间】:2019-04-29 04:15:33
【问题描述】:

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

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

【问题讨论】:

  • secret 变量上还有什么可用的吗?
  • 它包含这个类imgur.com/yfJLzUF
  • 您是否尝试并行进行秘密呼叫? Parallel.ForEach 方法。

标签: c# .net azure azure-keyvault


【解决方案1】:

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

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

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

【讨论】:

  • 您是否尝试并行进行秘密呼叫? Parallel.ForEach 方法。
【解决方案2】:

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

【讨论】:

    【解决方案3】:

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

    【讨论】:

    • 谢谢,这是我正在寻找的,也是最新的答案!
    【解决方案4】:

    如果您使用较新的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;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-18
      • 2021-05-12
      • 1970-01-01
      • 1970-01-01
      • 2016-10-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多