简体   繁体   中英

How should we use Azure key vault with IOptions<T> in Azure Function?

I am using IOptions pattern in my Azure function, and I am retrieving Mailjet keys from Azure key vault.

I have created below MailjetConfigOption class:

 public class MailjetConfigOption
    {
        public string PublicKey { get; set; }
      
        public string SecretKey { get; set; }

    }

And I have registered in the Startup.cs

[assembly: FunctionsStartup(typeof(Startup))]
namespace Emails.Dispatcher
{
    public class Startup : FunctionsStartup
    {
        public override void Configure(IFunctionsHostBuilder builder)
        {
            
            builder.Services.AddLogging();
            builder.Services.AddHttpClient();
            builder.Services.AddOptions<MailjetConfigOption>()
              .Bind(builder.GetContext().Configuration.GetSection(nameof(MailjetConfigOption)));

        }
    }
}

Below is my local.settings.json file:

"MailjetConfigOption:PublicKey": "load from key vault",
"MailjetConfigOption:SecretKey": "load from key vault",

Below is my key vault cache class which is added to load secrets from key vault.

 public static class KeyVaultCache
    {
        private const string KeyVaultSettingsUrl = "KeyVaultConfigOption:Url";
        private static Dictionary<string, string> SecretsCache = new Dictionary<string, string>();
        private static KeyVaultClient _KeyVaultClient = null;
        
        public static KeyVaultClient KeyVaultClient
        {
            get
            {
                if (_KeyVaultClient is null)
                {
                    var provider = new AzureServiceTokenProvider();
                    _KeyVaultClient = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(provider.KeyVaultTokenCallback));
                }
                return _KeyVaultClient;
            }
        }

        public async static Task<string> GetCachedSecret(string secretName)
        {
            if (!SecretsCache.ContainsKey(secretName))
            {
                string baseUri = GetBaseUri();

                var secretBundle = await KeyVaultClient.GetSecretAsync($"{baseUri}secrets/{secretName}");
                if (!SecretsCache.ContainsKey(secretName))
                    SecretsCache.Add(secretName, secretBundle.Value);
            }
            return SecretsCache.ContainsKey(secretName) ? SecretsCache[secretName] : string.Empty;
        }
       
        private static string GetBaseUri()
        {
            string baseUri = Environment.GetEnvironmentVariable(KeyVaultSettingsUrl, EnvironmentVariableTarget.Process);

            Ensure.ConditionIsMet(baseUri.IsNotNullOrEmpty(),
                () => new InvalidOperationException($"Unable to locate configured {KeyVaultSettingsUrl}"));

            return baseUri;
        }

Below is MailjetClientFactory class where I want to use IOptions, but it is loading configurations from local.settings.json instead of key vault, So How Can I retrieve these configurations from key vault? How can i use KeyVaultCache with MailjetConfigOption ?

public class MailjetClientFactory : IMailjetClientFactory
    {
        private readonly MailjetConfigOption _mailjetConfigOption;

        public MailjetClientFactory(IOptions<MailjetConfigOption> mailjetConfigOption)
        {
            _mailjetConfigOption = mailjetConfigOption.Value;
        }

        public IMailjetClient CreateClient()
        {
            return new MailjetClient(_mailjetConfigOption.PublicKey,
                _mailjetConfigOption.SecretKey)
            {
                Version = ApiVersion.V3_1
            };
        }      
    }

As you're reading using Environment.GetEnvironmentVariable, you can leverage Key Vault Reference which will retrieve the secrets for you.

Steps:

1-add a managed identity to you azure function app

2-add a policy in your Azure key Vault which will grant GET and LIST permission to the managed identity created on step 1

3-Use the key Vault Reference in Azure Function App Settings:

@Microsoft.KeyVault(SecretUri={SECRET_URL})

More Info:

https://docs.microsoft.com/en-us/azure/app-service/app-service-key-vault-references

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM