禁用的机密不允许 Azure Key Vault 操作获取

Azure Key Vault Operation get is not allowed on a disabled secret

我们已经在 .NET 核心应用程序中实现了 Azure 密钥保管库。一切正常,直到我们从列表中禁用秘密 - 在我的应用程序尝试再次获取列表后,它开始给我异常

Unhandled exception. Microsoft.Azure.KeyVault.Models.KeyVaultErrorException: Operation get is not allowed on a disabled secret.
   at Microsoft.Azure.KeyVault.KeyVaultClient.GetSecretWithHttpMessagesAsync(String vaultBaseUrl, String secretName, String secretVersion, Dictionary`2 customHeaders, CancellationToken cancellationToken)
   at Microsoft.Azure.KeyVault.KeyVaultClientExtensions.GetSecretAsync(IKeyVaultClient operations, String secretIdentifier, CancellationToken cancellationToken)
   at Microsoft.Extensions.Configuration.AzureKeyVault.AzureKeyVaultConfigurationProvider.LoadAsync()
   at Microsoft.Extensions.Configuration.AzureKeyVault.AzureKeyVaultConfigurationProvider.Load()
   at Microsoft.Extensions.Configuration.ConfigurationRoot..ctor(IList`1 providers)
   at Microsoft.Extensions.Configuration.ConfigurationBuilder.Build()
   at Microsoft.Extensions.Hosting.HostBuilder.BuildAppConfiguration()
   at Microsoft.Extensions.Hosting.HostBuilder.Build()
   at Vodafone.LandingPage.Program.Main(String[] args) in D:\a\s\src\LandingPage\Program.cs:line 30

我用来连接 program.cs 文件中的 Key Vault 的代码。

if (ctx.HostingEnvironment.IsProduction())
{
var builtConfig = builder.Build();

var keyVaultEndpoint = $"https://{builtConfig["AppSettings:KeyVaultName"]}.vault.azure.net/";
   

var azureServiceTokenProvider = new AzureServiceTokenProvider();
var keyVaultClient = new KeyVaultClient(
new KeyVaultClient.AuthenticationCallback(
azureServiceTokenProvider.KeyVaultTokenCallback));
builder.AddAzureKeyVault(keyVaultEndpoint, keyVaultClient, new DefaultKeyVaultSecretManager());
}

我们如何限制列表,使其不会将禁用的秘密放在一起。 我正在使用“获取”和“列表”权限。

appsettings.jsonappsettings 所做的更改。Environment.json 文件 after 应用程序启动由 JSON configuration provider.

读取

CreateDefaultBuilder()方法负责从appsettings.json

加载配置选项

CreateDefaultBuilder() 方法加载的设置可通过配置对象获得。

详情请参考bind configuration object with enabled secret and Read secrets from the settings file

经过研究,我找到了以下解决方案。

你可以这样使用它

问题:读取所有秘密的代码

builder.AddAzureKeyVault(keyVaultEndpoint, keyVaultClient, new DefaultKeyVaultSecretManager());

解决方案:只读启用机密的代码

builder.AddAzureKeyVault(keyVaultEndpoint,keyVaultClient,new PrefixKeyVaultSecretManager(keyVaultEndpoint));

IKeyVaultSecretManager 的实现

using System.Collections.Generic;
 using System.Text.RegularExpressions;
 using System.Threading.Tasks;
 using Microsoft.Azure.KeyVault;
 using Microsoft.Azure.KeyVault.Models;
 using Microsoft.Azure.Services.AppAuthentication;
 using Microsoft.Extensions.Configuration;
 using Microsoft.Extensions.Configuration.AzureKeyVault;

namespace KeyVaultPOC
{

public class PrefixKeyVaultSecretManager : IKeyVaultSecretManager
{
    
    private readonly IList<string> _overrides = new List<string>();

    public PrefixKeyVaultSecretManager(string vaultUrl)
    {           

        Task.Run(() => LoadListOfOverrides(vaultUrl)).Wait();
    }

    private async Task LoadListOfOverrides(string vaultUrl)
    {
        var azureServiceTokenProvider = new AzureServiceTokenProvider();
        var keyVaultClient = new KeyVaultClient(
            new KeyVaultClient.AuthenticationCallback(azureServiceTokenProvider.KeyVaultTokenCallback)
        );
                    
        var secrets = await keyVaultClient.GetSecretsAsync(vaultUrl);
        bool moreSecrets;

        do
        {
            foreach (var secret in secrets)
            {                    
                if ((bool)secret.Attributes.Enabled)
                {
                    _overrides.Add(secret.Identifier.Name);
                }
            }

            moreSecrets = !string.IsNullOrEmpty(secrets.NextPageLink);

            if (moreSecrets)
            {
                secrets = await keyVaultClient.GetSecretsNextAsync(secrets.NextPageLink);
            }
        } while (moreSecrets);
    }

    public bool Load(SecretItem secret)
    {
        
        return true;
    }

    public string GetKey(SecretBundle secret)
    {
        var key = secret.SecretIdentifier.Name;

        

        return key;
    }
}

}

参考:https://gist.github.com/davidxcheng/0576659d2c876d299619d979767dcdd6