Trying to access the object value from Azure key v

2020-07-27 03:59发布

问题:

I have an object value in the key vault key of azure and trying to read the value at the startup class but the value is always null.

Program.cs

var azureServiceTokenProvider = new AzureServiceTokenProvider();
                                var keyVaultClient = new KeyVaultClient(
                                    new KeyVaultClient.AuthenticationCallback(
                                        azureServiceTokenProvider.KeyVaultTokenCallback));

                                config.AddAzureKeyVault(
                                    vaultConfig.AzureVaultUrl,
                                    keyVaultClient,
                                    new DefaultKeyVaultSecretManager());

Startup.cs

public virtual void ConfigureSettings(IServiceCollection services)
    {
        services.AddOptions();
        services.Configure<OktaConfig>(Configuration.GetSection("OktaConfig")); // Read the value from Azure Key Vault or %APPDATA%\Microsoft\UserSecrets\<user_secrets_id>\secrets.json for Dev Environment
    }

Controller.cs

 public class SystemController
    {

        private readonly IConfiguration _config;
        private readonly OktaConfig _oktaConfig;

        public SystemController(IConfiguration config, IOptions<OktaConfig> oktaConfig)
        {
            _config = config;
            _oktaConfig = oktaConfig.Value; // This value is null
        }        


        [HttpGet("Vaults")]
        public IActionResult GetVaultValues()
        {
            var OktaConfig = JsonConvert.DeserializeObject<OktaConfig>(_config["OktaConfig"]);
            return Ok(OktaConfig);
        }

The _oktaConfig value is always null.

Here is my azure key vault value

Json structure of key secret value

{
        "OktaDomain": "https://dev-166545.okta.com/oauth2/XXXXXXXXXXXXXXXXX/v1/authorize",
        "ClientId": "XXXXXXXXXXXXXXXXXXXXXXXXXX",
        "ClientSecret": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
        "redirectUrl": "https://localhost:44307"
    }

ViewModel.cs

public class OktaConfig
    {
        public string RedirectUrl { get; set; }
        public string OktaDomain { get; set; }
        public string ClientId { get; set; }
        public string ClientSecret { get; set; }
        public string ClientName { get; set; }
    }

With this _config["OktaConfig"] code I am able to get the value, but I want to do dependency injection for that.

回答1:

I did a quick test on my side, this is my OktaConfig for quick test :

public class OktaConfig
{
    public string RedirectUrl { get; set; }   
}

Secret in key vault:

Other code are just same as you. But in Startup.cs , I use the code below to inject OktaConfig and add to services:

services.AddSingleton<OktaConfig>(sp =>
{
    var resultJson = Configuration.GetSection("<your secret name in kv>").Value;
    return JsonConvert.DeserializeObject<OktaConfig>(resultJson);
});

Code in controller:

private readonly ILogger<HomeController> _logger;
private OktaConfig oktaConfig;

public HomeController(ILogger<HomeController> logger , OktaConfig oktaConfig)
{
    this.oktaConfig = oktaConfig;
    _logger = logger;
}

public IActionResult Index()
{
    return Ok(oktaConfig.RedirectUrl);
}

Result:

Hope it helps.



回答2:

You want to map a key/value from KeyVault to a nested configuration, which is not possible. By default all secrets are written to root Configuration. However, IConfiguration implementation in netcore has a feature how to achieve this. For Example when you set the key "Section1:Key1" the section "Section1" key 'Key1' is set.

Configuration["Section1:Key1"]="value"
var section1 = Configuration.GetSection("Section1");

Now you only need to write the configuration from KeyVault to Configuration object in this format. DefaultKeyVaultSecretManager class can do this conversion for you, just save the key in KeyVault in appropriate format. Just write the separator '--' instead of ':' In my example you would use 'Section1--Key1'.

This article is very good source of information about this topic.