How to get connection string out of Azure KeyVault?

后端 未结 4 2079
花落未央
花落未央 2021-01-30 13:42

A hypothetical web-site currently connects using:

public SqlConnection CreateConnection()
{
   DbConnection connection = new SqlConnection();
   connection.Conne         


        
相关标签:
4条回答
  • 2021-01-30 14:27

    August 2020 update

    There's now a low-ceremony way to call Key Vault from App Service with zero custom code via Key Vault references. https://docs.microsoft.com/en-us/azure/app-service/app-service-key-vault-references

    App Setting example that populates value from Key Vault:

    @Microsoft.KeyVault(SecretUri=https://myvault.vault.azure.net/secrets/mysecret/ec96f02080254f109c51a1f14cdb1931)
    

    If you don't want the version identifier:

    @Microsoft.KeyVault(SecretUri=https://myvault.vault.azure.net/secrets/mysecret/)
    

    You need to setup Managed Identity first between your App Service instance and Key Vault to be able to use Key Vault references.

    I have nothing against Key Vault (i think it's a great product!), however i can't help myself but think you are overengineering this.

    I would simply use the built-in Application Settings functionality in Azure App Service:

    Connection strings

    For .NET apps, these connection strings are injected into your .NET configuration connectionStrings settings at runtime, overriding existing entries where the key equals the linked database name.

    Web App → Application Settings → Connection Strings → Add a Connection String and name it db.

    String GetConnectionString()
    {
       // Get the Connection String from Application Settings (App Service) 
       // with graceful fallback to web.config
       string cs = WebConfigurationManager.ConnectionStrings["db"].ConnectionString;
    
       if (cs == null)
          throw new Exception("Could not locate DB connection string");
    
       return cs;
    }
    

    What's the difference between the WebConfigurationManager and the ConfigurationManager?

    May 2018 update:

    Since Managed Service Identity became a thing, acquiring an access token no longer demands secrets (service principal credentials) being stored in your service to access Key Vault, which is a much better proposition. Here's a Node.js sample just to spice up this answer a little bit:

    // Get an access token from Managed Service Identity
    // on an Azure IaaS VM
    async function getAccessTokenWithMSI() {
      let msi = await axios.get('http://169.254.169.254/metadata/identity/oauth2/token',
        {
          params: {
            'api-version': '2018-02-01',
            'resource': 'https://vault.azure.net'
          },
          headers: {
            'Metadata': 'true'
          },
          timeout: 2000
        });
    
      return msi.data.access_token;
    }
    

    and then:

    // Get a secret from Key Vault
    async function getSecret(accessToken, secretUrl) {
      let response;
      try {
        response = await axios.get(secretUrl,
          {
             params: { 'api-version': '2016-10-01' },
             headers: { 'Authorization': `Bearer ${accessToken}` },
             timeout: 3000
          });
      }
      catch (e) {
        console.log('\nError calling Key Vault:,
            e.response.status, e.response.statusText, e.response.data);
      }
      console.log('\nGet Secret response from Key Vault: ',
          JSON.stringify(response.data, null, 4));
    
      return response.data;
    }
    
    0 讨论(0)
  • 2021-01-30 14:36

    For .net Core and already having Azure Key Vault in place. Now it's extremely easy. Let's assume your connection string is in your appsettings.json:

    {
       "ConnectionStrings": {
          "MyDatabase": "server=127.0.0.1;port=5678;database=mydb;user=FullMontyBurns;password=hunter2"
       } 
    }
    

    And you do your setup in Startup.cs:

    string connectionString = configuration.GetConnectionString("MyDatabase");
    

    In Azure Key Vault, create a secret:

    • Name: ConnectionStrings--MyDatabase
    • Value: server=127.0.0.1;port=5678;database=mydb;user=FullMontyBurns;password=hunter2

    The IConfiguration.GetConnectionString("MyDatabase") now takes the value from the Key Vault.

    0 讨论(0)
  • 2021-01-30 14:41

    Others have already provided great answers with context about how to integrate with a web app or Azure Function, but here are the definitive references for getting started with the Key Vault secrets SDK.

    .NET

    Java

    JavaScript

    Python

    0 讨论(0)
  • 2021-01-30 14:43

    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.

    0 讨论(0)
提交回复
热议问题