我正在使用示例代码在此处进行解释
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,而不是值。 我也想获得所有秘密的价值,所以任何人都可以帮助我做到这一点吗?
答案 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 方法。通过这种方式,您可以迭代并从保险库中获取所有机密。