Search code examples
azureasp.net-core-webapiazure-keyvaultappsettingsazure-storage-account

Access secret value in KV from appsetting of .net core app


I have deployed a .net core api application to send a message to queue by reading the connection string. I have given key vault administrator and key vault contributor to the identity of the app service. I placed the connection string in the appsettings.json and it worked. I placed the value of connection string in key vault and used the uri of the key vault and made required code changes and that worked as well.

Now I am referring the secret value in appsettings like below:

"MyConnectionString": "@Microsoft.KeyVault(SecretUri=https://my-kv.vault.azure.net/secrets/MyConnectionString/)"

And when I call the api I get 500 and when I saw logs from app service I see the below error:

Exception: 
System.FormatException: No valid combination of account information found.
   at Microsoft.WindowsAzure.Storage.CloudStorageAccount.<>c.<Parse>b__97_0(String err)
   at Microsoft.WindowsAzure.Storage.CloudStorageAccount.ParseImpl(String connectionString, CloudStorageAccount& accountInformation, Action`1 error)
   at Microsoft.WindowsAzure.Storage.CloudStorageAccount.Parse(String connectionString)

appsettings.json

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*",
  "MyConnectionString": "@Microsoft.KeyVault(SecretUri=https://my-kv.vault.azure.net/secrets/MyConnectionString/)"
  //"VaultName": "https://my-kv.vault.azure.net/"
}

using Microsoft.Extensions.Configuration;
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Queue;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace TestApp.Controllers
{
    public interface IMessageSender
    {
        Task Send(string content);
    }

    public class AzureQueueSender : IMessageSender
    {
        public AzureQueueSender(IConfiguration configuration)
        {
            Configuration = configuration;                
        }
        public IConfiguration Configuration { get; }
        public async Task Send(string content)
        {
            var connectionString = Configuration.GetValue<string>("MyConnectionString");
            await SendMessage(connectionString);
        }

        private static async Task SendMessage(string connectionString)
        {
            var storageAccount = CloudStorageAccount.Parse(connectionString);
            storageAccount.CreateCloudQueueClient();
            var queueClient = storageAccount.CreateCloudQueueClient();
            var queue = queueClient.GetQueueReference("queuename");
            var message = new CloudQueueMessage("Hello World!");
            await queue.AddMessageAsync(message);
        }
    }
}


Solution

  • To access and retrieve the Key Vault Secret value using the reference, we need to set the App setting in the deployed Azure App Service.

    The Key name must be same as the key which you have set in the local appsettings.json file.

    • As you have set the key with name MyConnectionString , Iam setting the same key-value in the Configuration section of the deployed app in portal.

    Azure App => Configuration => Application Setting = >New App Setting

    enter image description here

    Name : MyConnectionString
    Value:"@Microsoft.KeyVault(SecretUri=https://my-kv.vault.azure.net/secrets/MyConnectionString/)"
    
    • The App setting which you have set is now available in the Environment Variable (KUDU Console) with key APPSETTING_MyConnectionString.

    enter image description here

    Even we can retrieve the value as

    var myconn= Environment.GetEnvironmentVariable("APPSETTING_MyConnectionString");