Azure Key Vault:Get/Delete/Set 与 .NET Core 2.2 中的 KeyVaultClient 操作

Azure Key Vault: Get/Delete/Set operations with KeyVaultClient in .NET Core 2.2

我见过许多使用 IConfiguration 包括 this and this 检索机密的 Azure Key Vault 示例,但是这些主要涉及查看机密而不是 CRUD 类型操作。

我正在尝试使用 IKeyVaultClient 扩展方法,例如 GetSecretAsync 描述 here。为实现这一点,我在 Azure 中使用托管服务标识并执行了以下步骤(在典型的 Azure 配置之外):

  1. 创建一个 public IKeyVaultOps 接口和 KeyVaultOps 实现 public class 包含创建 KeyVaultClient.

KeyVaultOps.cs

public class KeyVaultOps : IKeyVaultOps
{
    public KeyVaultClient GetKeyVaultClient()
    {
        AzureServiceTokenProvider azureServiceTokenProvider = new AzureServiceTokenProvider();
        return new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(azureServiceTokenProvider.KeyVaultTokenCallback));
    }
}
  1. 必要时使用DI注入:

Startup.cs

services.AddSingleton<IKeyVaultOps, KeyVaultOps>();

Razor 页面:

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

认识到我实际上并不需要一个界面来让它正常工作,我正在寻找关于两件事的建议:

  1. 有没有比在每个 class 上注入 IConfiguration 更好的方法来配置 KeyVaultClient URL 属性 我需要实施?

  2. 因为我的主要项目有 using 语句 Microsoft.Azure.KeyVault 无论如何,有没有办法避免我自己的 GetKeyVaultClient() 实现并简单地使用:

    services.AddSingleton<IKeyVaultClient, KeyVaultClient>();

...以及必要的扩展方法?

注意:Startup.cs 中的上述行产生:

No constructor for type 'Microsoft.Azure.KeyVault.KeyVaultClient' can be instantiated using services from the service container and default values

我喜欢创建自己的服务来访问为我处理 URL 和身份验证的密钥保管库,因此我的代码可以简单地使用该服务而无需考虑配置。它的工作原理是这样的:

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(),而不必担心细节。