简体   繁体   English

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

[英]How to get all secrets in one call Azure key vault

I am using sample code explain here我在这里使用示例代码说明

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

but they only explained how can we get single secrete not list of secrete.但他们只解释了我们如何才能获得单一的秘密而不是秘密列表。

so to get all secrete I'm using this code sample所以为了得到所有的秘密,我正在使用这个代码示例

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

but it is only getting the secret id, not value.但它只是获取秘密ID,而不是价值。 I want to get all secrets value also so can anyone help how I can do this?我也想获得所有秘密的价值,所以任何人都可以帮助我如何做到这一点?

Looking at the documentation, the KeyVaultClient Class doesn't contain a method to get all secrets including their values.查看文档, KeyVaultClient不包含获取所有机密(包括其值)的方法。 The GetSecrets method 'List secrets in a specified key vault.' GetSecrets方法“列出指定密钥保管库中的机密”。 and returns a list with items of type SecretItem , which doesn't contain the value but only contains secret metadata.并返回一个包含SecretItem类型项目的列表,该列表不包含值,但仅包含秘密元数据。

This is in line with the Key Vault REST API, where there's a GetSecrets that returns... you guessed it... a list of SecretItems.这与 Key Vault REST API 一致,其中有一个GetSecrets返回......你猜对了...... SecretItems 列表。

Long story short: if you want all values of all secrets, you have to iterate the list and get every one explicitly.长话短说:如果你想要所有秘密的所有值,你必须迭代列表并明确获取每一个。

You have to get all secrets, returning an IPage of SecretItem, and then iterate through each one to get the SecretBundle like this.您必须获取所有秘密,返回 SecretItem 的 IPage,然后遍历每个秘密以获得这样的 SecretBundle。 Here's my code that handles the operation:这是我处理操作的代码:

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;
        }
    }
}

For testing purposes I have registered an application to access my Azure instances, and to initialize the class all I do is:出于测试目的,我注册了一个应用程序来访问我的 Azure 实例,并初始化该类,我所做的只是:

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

and then can call:然后可以调用:

credentials["<secretName>"];

If you are using the newer Azure.Security.KeyVault.Secrets package then you can get all the secrets by using the GetPropertiesOfSecretsAsync method, then iterating over each result calling GetSecretAsync .如果您使用的是较新的Azure.Security.KeyVault.Secrets包,则可以使用GetPropertiesOfSecretsAsync方法获取所有机密,然后遍历调用GetSecretAsync的每个结果。 Obviously this is still SELECT N+1 but there currently appears to still be no other way to do this.显然这仍然是SELECT N+1但目前似乎仍然没有其他方法可以做到这一点。

Note that you will need to be using C# 8.0 to use this example:请注意,您需要使用 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;
}

You can use listPropertiesOfSecrets method which returns all keys.您可以使用返回所有密钥的 listPropertiesOfSecrets 方法。 This way you can iterate and get all secrets from vault.通过这种方式,您可以迭代并从保险库中获取所有秘密。

We can find all keys like this我们可以找到所有这样的键

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM