How to get connection string out of Azure KeyVault?

azure, azure-keyvault, c#, connection-string, security

Solution

What is the actual api?

We could use the GetSecret API to get value.

Preparation:

Registry Azure Active Directory application and assign Role

Steps:

1.Create KeyVault and add secret from Azure portal

2.Config Access policy

3.Get Access token

 var context = new AuthenticationContext("https://login.windows.net/" + tenantId);
            ClientCredential clientCredential = new ClientCredential(appId, secretKey);
            var tokenResponse =await context.AcquireTokenAsync("https://vault.azure.net", clientCredential);
            var accessToken = tokenResponse.AccessToken;
            return accessToken;

Note: The resource for Keyvault is `https://vault.azure.net`

4.Test with Fiddler

We also can do that easily with SDK:

1.Create a console project and a Utils.cs file

public static string EncryptSecret { get; set; }
        static string appId = "Application ID";
        static string secretKey = "Secert key";
        static string tenantId = "TenantId";

        public static async Task<string> GetAccessToken(string azureTenantId,string azureAppId,string azureSecretKey)
        {

            var context = new AuthenticationContext("https://login.windows.net/" + tenantId);
            ClientCredential clientCredential = new ClientCredential(appId, secretKey);
            var tokenResponse =await context.AcquireTokenAsync("https://vault.azure.net", clientCredential);
            var accessToken = tokenResponse.AccessToken;
            return accessToken;
        }

2.Add the follow code in the main function and test it.

packages.config file

<?xml version="1.0" encoding="utf-8"?>
<packages>
  <package id="Hyak.Common" version="1.0.2" targetFramework="net452" />
  <package id="Microsoft.Azure.Common" version="2.0.4" targetFramework="net452" />
  <package id="Microsoft.Azure.Common.Dependencies" version="1.0.0" targetFramework="net452" />
  <package id="Microsoft.Azure.KeyVault" version="1.0.0" targetFramework="net452" />
  <package id="Microsoft.Bcl" version="1.1.9" targetFramework="net452" />
  <package id="Microsoft.Bcl.Async" version="1.0.168" targetFramework="net452" />
  <package id="Microsoft.Bcl.Build" version="1.0.14" targetFramework="net452" />
  <package id="Microsoft.IdentityModel.Clients.ActiveDirectory" version="3.13.9" targetFramework="net452" />
  <package id="Microsoft.Net.Http" version="2.2.22" targetFramework="net452" />
  <package id="Newtonsoft.Json" version="6.0.4" targetFramework="net452" />
</packages>

We also can get more information from CtrlDot mentioned document.

Problem

A hypothetical web-site currently connects using: ``` public SqlConnection CreateConnection() { DbConnection connection = new SqlConnection(); connection.ConnectionString = GetConnectionString(); connection.Open(); return connection; } ``` Where the magical connection string is stored in `web.config`: ``` String GetConnectionString() { //Get the connection string info from web.config ConnectionStringSettings cs = ConfigurationManager.ConnectionStrings["db"]; if (cs == null) throw new Exception("Could not locate DB connection string"); return cs.ConnectionString; } ``` Now i'd like to move the connection string out of the web.config file into Azure KeyVault. How do you retrieve anything out of the Azure key vault? ``` String GetConnectionString() { //Get the connection string info from Azure KeyVault String connectionString = GetAzureSecret("dbConnectionString"); if (String.IsNullOrWhitespace(connectionString) throw new Exception.Create("Could not connection string of Azure Key Vault"); return connectionString; } ``` Except i just made up the easy-to-use Azure API. What is the actual api? Untested attempt ``` string GetAzureSecret(string key) { KeyVaultClient vault = new KeyVaultClient(); vault.OnAuthenticate += VaultClientAuthenticate; var sec = await vault.GetSecretAsync(Key); return sec.Value; } public static async Task<string> VaultClientAuthenticate(string authority, string resource, string scope) { String clientID = "8675209"; String clientSecret = "correct battery horse pencil"; var authContext = new AuthenticationContext(authority); ClientCredential clientCred = new ClientCredential(clientID, clientSecret); AuthenticationResult result = await authContext.AcquireTokenAsync(resource, clientCred); if (result == null) throw new Exception("Could not acquire token"); return result.AccessToken; } ``` Bonus Reading - MSDN Forums: Storing sql connection string passwords in Key Vault for my Cloud Services - How to properly store connection strings in Azure? - Easily switching ConnectionStrings on publish to Azure

Original source

Related problems