我已经看到许多用于使用IConfiguration
来检索机密的Azure Key Vault的示例,包括this和this,但是这些示例主要处理查看机密而不是CRUD类型的操作。
我正在尝试使用IKeyVaultClient
这样的GetSecretAsync
扩展方法来描述here。为实现此目的,我在Azure中使用托管服务标识,并执行了以下步骤(在典型的Azure配置之外):
IKeyVaultOps
接口,并KeyVaultOps
实现包含创建KeyVaultClient
的公共类。public class KeyVaultOps : IKeyVaultOps
{
public KeyVaultClient GetKeyVaultClient()
{
AzureServiceTokenProvider azureServiceTokenProvider = new AzureServiceTokenProvider();
return new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(azureServiceTokenProvider.KeyVaultTokenCallback));
}
}
services.AddSingleton<IKeyVaultOps, KeyVaultOps>();
private readonly IKeyVaultOps keyVaultOps;
private readonly IConfiguration configuration;
public TestPageModel(
IKeyVaultOps keyVaultOps,
IConfiguration configuration
)
{
this.keyVaultOps = keyVaultOps;
this.configuration = configuration;
}
public string Secret { get; set; }
public class TestPageModel : PageModel
{
public async Task OnGetAsync()
{
try
{
var vaultUrl = configuration["KeyVaultUrl"];
SecretBundle secretBundle = await keyVaultOps.GetKeyVaultClient().GetSecretAsync(vaultUrl, "TestSecret");
Secret = secretBundle.Value;
}
catch (Exception ex)
{
Secret = ex.Message;
}
}
}
认识到我实际上不需要界面即可正常工作,我在寻找关于以下两点的建议:
是否有比配置KeyVaultClient
更好的方法来配置IConfiguration
URL属性?
由于我的主项目仍然有using
的{{1}}语句,有没有一种方法可以避免我自己的Microsoft.Azure.KeyVault
的实现,只需使用:
GetKeyVaultClient()
...还有必要的扩展方法?
注意:services.AddSingleton<IKeyVaultClient, KeyVaultClient>();
中的上述行产生:
不能使用服务容器中的服务和默认值实例化'Microsoft.Azure.KeyVault.KeyVaultClient'类型的构造函数
答案 0 :(得分:0)
我喜欢创建自己的服务来访问为我处理URL和auth内容的密钥库,因此我的代码可以简单地使用该服务而无需进行配置。它的工作原理如下:
public interface IMyKeyVaultClient {
Task<SecretBundle> GetSecretAsync(string secretName);
}
public class MyKeyVaultClient : IMyKeyVaultClient {
public MyKeyVaultClient(IConfiguration config, IWhateverElseYouNeedForGettingCredentials otherStuff) {
//snag the URL from config and credentials from otherStuff
//instantiate keyVaultClient;
}
private KeyVaultClient keyVaultClient;
private string url;
public Task<SecretBundle> GetSecretAsync(string secretName) {
return keyVaultClient.GetSecretAsync(url, secretName);
}
}
然后注册您的服务,
services.AddSingleton<IMyKeyVaultClient, MyKeyVaultClient>();
然后,您的调用代码可以简单地从DI请求一个IMyKeyVaultClient
并仅使用一个秘密名称来调用GetSecretAsync()
,而不必担心细节。