假设我想要一个接口和类来存储来自外部提供商(例如 Azure KeyVault)的键值对。
我有这个界面:
namespace SampleNamespace.Interfaces
{
public interface IKeyVault
{
string string1 { get; }
string string2 { get; }
string string3 { get; }
//... more member variables
string stringN { get; }
//initialize the class with the values from the keyvault
public Task<bool> Initialize();
}
}
然后我就有了这个接口的实现:
namespace SampleNamespace.Classes
{
public class AzureKeyVault : IKeyVault
{
string string1 { get; private set; }
string string2 { get; private set; }
string string3 { get; private set; }
...
string stringN { get; private set; }
public async Task<bool> Initialize()
{
if (AzureKeyVaultProvider.InitializeClient("somekey"))
{
string1 = await AzureKeyVaultProvider.GetSecret("string1");
//...more fetches
stringN = await AzureKeyVaultProvider.GetSecret("stringN");
return true;
}
return false;
}
}
}
您可以想象这些获取需要一些时间(对于 6 个值,大约需要 4 秒)。并非每个使用和初始化该类的服务都需要每个值。此外,将来可能会添加一些其他值到远程保管库(无论是什么,因此是接口)。如何使变量动态化,并使类的每个初始化器仅获取和初始化它需要的变量?
我尝试根据调用服务制作许多初始化程序,但这使得接口的使用违反直觉。另外,我不想实现异步获取每个值的 getter 函数。我想在我的代码中的一处初始化所需的。
也许这更多的是评论而不是答案,但作为 Key Vault SDK for .NET 的当前所有者,我可以告诉您,根据设计,您无法在一次调用中获取多个秘密值。列出和获取秘密是不同的操作,需要单独的权限,即
secret/list
和 secret/get
。
如果您知道在某些时候您将需要多个值,我们实际上建议您以这种方式存储它们。这实际上很常见。您可以将类序列化为 JSON,并将其作为 JSON blob 存储和检索,例如:
SecretClient client = new SecretClient(vaultUri, credential);
KeyVaultSecret secret = await client.GetSecretAsync(secretName);
Secrets secrets = JsonSerializer.Deserialize(secret.Value, SecretsGenerationContext.Default.Secrets)
?? throw new Exception("Corrupted secret");
Console.WriteLine($"Secret1: {secrets.Secret1}");
Console.WriteLine($"Secret2: {secrets.Secret2}");
class Secrets
{
public string? Secret1 { get; set; }
public string? Secret2 { get; set; }
}
[JsonSerializable(typeof(Secrets))]
[JsonSourceGenerationOptions(PropertyNameCaseInsensitive = true, WriteIndented = true)]
partial class SecretsGenerationContext : JsonSerializerContext {};
与单独检索每个相比,这种方式会快得多。如果您使用的是旧版访问策略,则无论如何都无法对单个机密设置权限。尽管这应该可以通过 RBAC 实现,但您可能会发现使用单独的 Key Vault 管理单独的应用程序更容易,这也可能有助于降低成本,即使 Key Vault 已经相当便宜。