Tutorial: Use Azure Key Vault with an Azure web app in .NET

Azure Key Vault helps you protect secrets such as API keys and database connection strings. It provides you with access to your applications, services, and IT resources.

In this tutorial, you learn how to create an Azure web application that can read information from an Azure key vault. The process uses managed identities for Azure resources. For more information about Azure web applications, see Azure App Service.

The article shows you how to:

  • Create a key vault.
  • Store a secret in the key vault.
  • Retrieve a secret from the key vault.
  • Create an Azure web application.
  • Enable a managed identity for the web app.
  • Grant the required permissions for the web application to read data from the key vault.
  • Run the web application on Azure.

Before proceeding, read Key Vault basic concepts.

Prerequisites

Managed Service Identity and how it works

Azure Key Vault stores credentials securely so they aren’t in your code. However, you need to authenticate to Azure Key Vault to retrieve your keys. To authenticate to Key Vault, you need a credential. It's a classic bootstrap dilemma. Managed Service Identity (MSI) solves this issue by providing a bootstrap identity that simplifies the process.

When you enable MSI for an Azure service (for example: Virtual Machines, App Service, or Functions), Azure creates a Service Principal. MSI does this for the instance of the service in Azure Active Directory (Azure AD) and injects the credentials for the Service Principal into that instance.

MSI diagram

Next, your code calls a local metadata service available on the Azure resource to get an access token. Your code uses the access token it gets from the local MSI_ENDPOINT to authenticate to an Azure Key Vault service.

Sign in to Azure

To sign in to Azure by using the Azure CLI, enter:

az login

Create a resource group

An Azure resource group is a logical container into which Azure resources are deployed and managed.

  1. Create a resource group by using the az group create command.
  2. Select a resource group name and fill in the placeholder. The following example creates a resource group in the West US location:

    # To list locations: az account list-locations --output table
    az group create --name "<YourResourceGroupName>" --location "West US"
    

You use this resource group throughout this tutorial.

Create a key vault

To create a key vault in your resource group, provide the following information:

  • Key vault name: a string of 3 to 24 characters that can contain only numbers, letters, and hyphens (for example: 0-9, a-z, A-Z, and - )
  • Resource group name
  • Location: West US

Enter the following command in the Azure CLI:

az keyvault create --name "<YourKeyVaultName>" --resource-group "<YourResourceGroupName>" --location "West US"

At this point, your Azure account is the only one that's authorized to perform any operations on this new vault.

Add a secret to the key vault

Now you can add a secret. It might be a SQL connection string or any other information that you need to keep both secure and available to your application.

Type the following command to create a secret in the key vault called AppSecret. This secret stores the value MySecret.

az keyvault secret set --vault-name "<YourKeyVaultName>" --name "AppSecret" --value "MySecret"

To view the value contained in the secret as plain text, enter the following command:

az keyvault secret show --name "AppSecret" --vault-name "<YourKeyVaultName>"

This command shows the secret information, including the URI. After you complete these steps, you should have a URI to a secret in a key vault. Make note of this information. You'll need it in a later step.

Create a .NET Core web app

Follow this tutorial to create a .NET Core web app and publish it to Azure. You can also watch the following video:

Open and edit the solution

  1. Browse to the Pages > About.cshtml.cs file.
  2. Install these NuGet packages:
  3. Import the following code in the About.cshtml.cs file:

     using Microsoft.Azure.KeyVault;
     using Microsoft.Azure.KeyVault.Models;
     using Microsoft.Azure.Services.AppAuthentication;
    
  4. Your code in the AboutModel class should like this:

     public class AboutModel : PageModel
     {
         public string Message { get; set; }
    
         public async Task OnGetAsync()
         {
             Message = "Your application description page.";
             int retries = 0;
             bool retry = false;
             try
             {
                 /* The below 4 lines of code shows you how to use AppAuthentication library to fetch secrets from your Key Vault*/
                 AzureServiceTokenProvider azureServiceTokenProvider = new AzureServiceTokenProvider();
                 KeyVaultClient keyVaultClient = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(azureServiceTokenProvider.KeyVaultTokenCallback));
                 var secret = await keyVaultClient.GetSecretAsync("https://<YourKeyVaultName>.vault.azure.net/secrets/AppSecret")
                         .ConfigureAwait(false);
                 Message = secret.Value;
    
                 /* The below do while logic is to handle throttling errors thrown by Azure Key Vault. It shows how to do exponential backoff which is the recommended client side throttling*/
                 do
                 {
                     long waitTime = Math.Min(getWaitTime(retries), 2000000);
                     secret = await keyVaultClient.GetSecretAsync("https://<YourKeyVaultName>.vault.azure.net/secrets/AppSecret")
                         .ConfigureAwait(false);
                     retry = false;
                 } 
                 while(retry && (retries++ < 10));
             }
             /// <exception cref="KeyVaultErrorException">
             /// Thrown when the operation returned an invalid status code
             /// </exception>
             catch (KeyVaultErrorException keyVaultException)
             {
                 Message = keyVaultException.Message;
                 if((int)keyVaultException.Response.StatusCode == 429)
                     retry = true;
             }
         }
    
         // This method implements exponential backoff incase of 429 errors from Azure Key Vault
         private static long getWaitTime(int retryCount)
         {
             long waitTime = ((long)Math.Pow(2, retryCount) * 100L);
             return waitTime;
         }
    
         // This method fetches a token from Azure Active Directory which can then be provided to Azure Key Vault to authenticate
         public async Task<string> GetAccessTokenAsync()
         {
             var azureServiceTokenProvider = new AzureServiceTokenProvider();
             string accessToken = await azureServiceTokenProvider.GetAccessTokenAsync("https://vault.azure.net");
             return accessToken;
         }
     }
    

Run the app

  1. From the main menu of Visual Studio 2017, select Debug > Start with or without debugging.
  2. When the browser appears, go to the About page.
  3. The value for AppSecret is displayed.

Enable a managed identity for the web app

Azure Key Vault provides a way to securely store credentials and other secrets, but your code needs to authenticate to Key Vault to retrieve them. Managed identities for Azure resources overview helps to solve this problem by giving Azure services an automatically managed identity in Azure AD. You can use this identity to authenticate to any service that supports Azure AD authentication, including Key Vault, without having any credentials in your code.

  1. In the Azure CLI, run the assign-identity command to create the identity for this application:

    
    az webapp identity assign --name "<YourAppName>" --resource-group "<YourResourceGroupName>"
    

    Note

    You have to replace <YourAppName> with the name of the published app on Azure. For example, if your published app name was MyAwesomeapp.azurewebsites.net, replace <YourAppName> with MyAwesomeapp.

  2. Make a note of the PrincipalId when you publish the application to Azure. The output of the command in step 1 should be in the following format:

    {
      "principalId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
      "tenantId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
      "type": "SystemAssigned"
    }
    

Note

The command in this procedure is the equivalent of going to the portal and switching the Identity / System assigned setting to On in the web application properties.

Assign permissions to your application to read secrets from Key Vault

Replace <YourKeyVaultName> with the name of your key vault and <PrincipalId> with the value of the PrincipalId in the following command:

az keyvault set-policy --name '<YourKeyVaultName>' --object-id <PrincipalId> --secret-permissions get list

This command gives the identity (MSI) of the app service permissions to do get and list operations on your key vault.

Publish the web application to Azure

Publish your web app to Azure once again to see that your live web app can fetch the secret value.

  1. In Visual Studio, select the key-vault-dotnet-core-quickstart project.
  2. Select Publish > Start.
  3. Select Create.

When you run the application, you should see that it can retrieve your secret value.

Now, you've now successfully created a web app in .NET that stores and fetches its secrets from Key Vault.

Next steps