我在这里使用示例代码解释
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,而不是值。 我也想获得所有秘密的价值,所以有人可以帮助我如何做到这一点吗?
我们可以这样找到所有的钥匙
var secretClient = new SecretClient(new Uri($"https://{AzureKeyVaultName}.vault.azure.net/"), new DefaultAzureCredential());
var v = secretClient.GetPropertiesOfSecrets().AsPages().ToList();
KeyVaultClient
Class不包含获取所有秘密(包括其值)的方法。 GetSecrets
方法“列出指定密钥保管库中的机密。”并返回一个包含类型为 SecretItem
的项目的列表,该列表不包含值,仅包含秘密元数据。
这与 Key Vault REST API 一致,其中有一个 GetSecrets 返回...您猜对了...SecretItems 列表。
长话短说:如果您想要所有秘密的所有值,则必须迭代列表并显式获取每个值。
如果您使用较新的
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;
}
您可以使用 listPropertiesOfSecrets 方法返回所有键。这样您就可以迭代并从保管库中获取所有秘密。
你必须获取所有秘密,返回 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>"];
使用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}");
}
}
}
}
}