Giter Club home page Giter Club logo

app-service-msi-keyvault-dotnet's Introduction

page_type languages products description urlFragment
sample
csharp
azure
dotnet
aspnet
azure-app-service
azure-key-vault
This sample shows how to use Azure KeyVault from App Service with Managed Service Identity (MSI).
keyvault-msi-appservice-sample

Use Key Vault from App Service with Managed Service Identity

Background

For Service-to-Azure-Service authentication, the approach so far involved creating an Azure AD application and associated credential, and using that credential to get a token. The sample here shows how this approach is used to authenticate to Azure Key Vault from a Web App. While this approach works well, there are two shortcomings:

  1. The Azure AD application credentials are typically hard coded in source code. Developers tend to push the code to source repositories as-is, which leads to credentials in source.
  2. The Azure AD application credentials expire, and so need to be renewed, else can lead to application downtime.

With Managed Service Identity (MSI), both these problems are solved. This sample shows how a Web App can authenticate to Azure Key Vault without the need to explicitly create an Azure AD application or manage its credentials.

Here's another sample that shows how to programatically deploy an ARM template from a .NET Console application running on an Azure VM with a Managed Service Identity (MSI) - https://github.com/Azure-Samples/windowsvm-msi-arm-dotnet

Here's another .NET Core sample that shows how to programmatically call Azure Services from an Azure Linux VM with a Managed Service Identity (MSI). - https://github.com/Azure-Samples/linuxvm-msi-keyvault-arm-dotnet

Prerequisites

To run and deploy this sample, you need the following:

  1. An Azure subscription to create an App Service and a Key Vault.
  2. Azure CLI 2.0 to run the application on your local development machine.

Step 1: Create an App Service with a Managed Service Identity (MSI)

Use the "Deploy to Azure" button to deploy an ARM template to create the following resources:

  1. App Service with MSI.
  2. Key Vault with a secret, and an access policy that grants the App Service access to Get Secrets.

Note: When filling out the template you will see a textbox labelled 'Key Vault Secret'. Enter a secret value there. A secret with the name 'secret' and value from what you entered will be created in the Key Vault.

Review the resources created using the Azure portal. You should see an App Service and a Key Vault. View the access policies of the Key Vault to see that the App Service has access to it.

Step 2: Grant yourself data plane access to the Key Vault

Using the Azure Portal, go to the Key Vault's access policies, and grant yourself Secret Management access to the Key Vault. This will allow you to run the application on your local development machine.

  1. Search for your Key Vault in “Search Resources dialog box” in Azure Portal.
  2. Select "Overview", and click on Access policies
  3. Click on "Add New", select "Secret Management" from the dropdown for "Configure from template"
  4. Click on "Select Principal", add your account
  5. Click on "OK" to add the new Access Policy, then click "Save" to save the Access Policies

Step 3: Clone the repo

Clone the repo to your development machine.

The project has two relevant Nuget packages:

  1. Microsoft.Azure.Services.AppAuthentication - makes it easy to fetch access tokens for Service-to-Azure-Service authentication scenarios.
  2. Microsoft.Azure.KeyVault - contains methods for interacting with Key Vault.

The relevant code is in WebAppKeyVault/WebAppKeyVault/Controllers/HomeController.cs file. The AzureServiceTokenProvider class (which is part of Microsoft.Azure.Services.AppAuthentication) tries the following methods to get an access token:-

  1. Managed Service Identity (MSI) - for scenarios where the code is deployed to Azure, and the Azure resource supports MSI.
  2. Azure CLI (for local development) - Azure CLI version 2.0.12 and above supports the get-access-token option. AzureServiceTokenProvider uses this option to get an access token for local development.
  3. Active Directory Integrated Authentication (for local development). To use integrated Windows authentication, your domain’s Active Directory must be federated with Azure Active Directory. Your application must be running on a domain-joined machine under a user’s domain credentials.
public async System.Threading.Tasks.Task<ActionResult> Index()
{
    AzureServiceTokenProvider azureServiceTokenProvider = new AzureServiceTokenProvider();

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

        var secret = await keyVaultClient.GetSecretAsync("https://keyvaultname.vault.azure.net/secrets/secret")
            .ConfigureAwait(false);

        ViewBag.Secret = $"Secret: {secret.Value}";
        
    }
    catch (Exception exp)
    {
        ViewBag.Error = $"Something went wrong: {exp.Message}";
    }

    ViewBag.Principal = azureServiceTokenProvider.PrincipalUsed != null ? $"Principal Used: {azureServiceTokenProvider.PrincipalUsed}" : string.Empty;

    return View();
}

Step 4: Replace the key vault name

In the HomeController.cs file, change the Key Vault name to the one you just created. Replace KeyVaultName with the name of your Key Vault.

Step 5: Run the application on your local development machine

AzureServiceTokenProvider will use the developer's security context to get a token to authenticate to Key Vault. This removes the need to create a service principal, and share it with the development team. It also prevents credentials from being checked in to source code. AzureServiceTokenProvider will use Azure CLI or Active Directory Integrated Authentication to authenticate to Azure AD to get a token. That token will be used to fetch the secret from Azure Key Vault.

Azure CLI will work if the following conditions are met:

  1. You have Azure CLI 2.0 installed. Version 2.0.12 supports the get-access-token option used by AzureServiceTokenProvider. If you have an earlier version, please upgrade.
  2. You are logged into Azure CLI. You can login using az login command.

Azure Active Directory Authentication will only work if the following conditions are met:

  1. Your on-premise active directory is synced with Azure AD.
  2. You are running this code on a domain joined machine.

Since your developer account has access to the Key Vault, you should see the secret on the web page. Principal Used will show type "User" and your user account.

You can also use a service principal to run the application on your local development machine. See the section "Running the application using a service principal" later in the tutorial on how to do this.

Step 6: Deploy the Web App to Azure

Use any of the methods outlined on Deploy your app to Azure App Service to publish the Web App to Azure. After you deploy it, browse to the web app. You should see the secret on the web page, and this time the Principal Used will show "App", since it ran under the context of the App Service. The AppId of the MSI will be displayed.

Summary

The web app was successfully able to get a secret at runtime from Azure Key Vault using your developer account during development, and using MSI when deployed to Azure, without any code change between local development environment and Azure. As a result, you did not have to explicitly handle a service principal credential to authenticate to Azure AD to get a token to call Key Vault. You do not have to worry about renewing the service principal credential either, since MSI takes care of that.

Running the application using a service principal in local development environment

Note: It is recommended to use your developer context for local development, since you do not need to create or share a service principal for that. If that does not work for you, you can use a service principal, but do not check in the certificate or secret in source repos, and share them securely.

To run the application using a service principal in the local development environment, follow these steps

Service principal using a certificate:

  1. Create a service principal certificate. Follow steps here to create a service principal and grant it permissions to the Key Vault.
  2. Set an environment variable named AzureServicesAuthConnectionString to RunAs=App;AppId=AppId;TenantId=TenantId;CertificateThumbprint=Thumbprint;CertificateStoreLocation=CurrentUser. You need to replace AppId, TenantId, and Thumbprint with actual values from step #1.
  3. Run the application in your local development environment. No code change is required. AzureServiceTokenProvider will use this environment variable and use the certificate to authenticate to Azure AD.

Service principal using a password:

  1. Create a service principal with a password. Follow steps here to create a service principal and grant it permissions to the Key Vault.
  2. Set an environment variable named AzureServicesAuthConnectionString to RunAs=App;AppId=AppId;TenantId=TenantId;AppKey=Secret. You need to replace AppId, TenantId, and Secret with actual values from step #1.
  3. Run the application in your local development environment. No code change is required. AzureServiceTokenProvider will use this environment variable and use the service principal to authenticate to Azure AD.

Troubleshooting

Please see the troubleshooting section of the AppAuthentication library documentation for troubleshooting of common issues.

app-service-msi-keyvault-dotnet's People

Contributors

cawams avatar microsoftopensource avatar msftgits avatar nonik0 avatar supernova-eng avatar tvand7093 avatar

Stargazers

 avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.