2
votes

I'm wondering if there is a way I can setup a .net mvc app the same way a .net core app can be setup with Key Vault.

https://docs.microsoft.com/en-us/aspnet/core/security/key-vault-configuration?view=aspnetcore-2.2#secret-storage-in-the-development-environment

I want to be able to pull secrets in my local development environment without provisioning an Azure Key Vault.

In a .net core app I was able to follow the above link and get everything working.

// ran this command in powershell
dotnet user-secrets set "db-connection-string" "db-connection-string-value"

Setup the key vault with an empty endpoint in Program.cs (this is just for testing).

public static IWebHost BuildWebHost(string[] args) =>
           WebHost.CreateDefaultBuilder(args)
               .ConfigureAppConfiguration((ctx, builder) =>
               {
                   var keyVaultEndpoint = GetKeyVaultEndpoint();
                   if (!string.IsNullOrEmpty(keyVaultEndpoint))
                   {
                       var azureServiceTokenProvider = new AzureServiceTokenProvider();
                       var keyVaultClient = new KeyVaultClient(
                           new KeyVaultClient.AuthenticationCallback(
                               azureServiceTokenProvider.KeyVaultTokenCallback));
                       builder.AddAzureKeyVault(
                           keyVaultEndpoint, keyVaultClient, new DefaultKeyVaultSecretManager());
                   }
               }
            ).UseStartup<Startup>()
             .Build();

        private static string GetKeyVaultEndpoint() => "";

And I am able to access my secret locally using the below code.

 public void OnGet()
        {
            Message = "My key val = " + _configuration["db-connection-string"];
        }

In my asp.net app I am able to pull secrets from an Azure Key Vault. I just don't want to have to do that when developing locally since each developer could have a slightly different connection string to their local database, and requiring them to use a Key Vault in Azure is going to be annoying and cause frustration. Maybe we shouldn't use Key Vault for "legacy" applications. Any help is appreciated.

1

1 Answers

5
votes

This seems similar to our development environment.

We wanted developers to use some values from the key vault, but to be able to override particular values for their local environment. (particularly the database connection string).

In the ConfigureAppConfiguration method you can register multiple configuration providers. If two configuration providers write to the same configuration key, the last registered provider gets precedence.

Knowing this, you can have a local file appSettings.json, which defines the database connection string:

{
     "db-connection-string": "Data Source = DEVELOPMENT_PC;Initial Catalog=MyLocalDatabase;Integrated Security=True"
}

Then register this provider after you have registered the key vault provider.

.ConfigureAppConfiguration((ctx, builder) =>
{
    var keyVaultEndpoint = GetKeyVaultEndpoint();
    if (!string.IsNullOrEmpty(keyVaultEndpoint))
    {
        var azureServiceTokenProvider = new AzureServiceTokenProvider();
        var keyVaultClient = new KeyVaultClient(
            new KeyVaultClient.AuthenticationCallback(
                azureServiceTokenProvider.KeyVaultTokenCallback
            )
        );
        builder.AddAzureKeyVault(
            keyVaultEndpoint,
            keyVaultClient,
            new DefaultKeyVaultSecretManager()
        );
    }

    var appSettingsFilePath = GetJsonAppSettingsFile(); // Hardcoded, or add some other configuratin logic
    if (!string.IsNullOrEmpty(appSettingsFilePath))
    {
        builder.AddJsonFile(appSettingsFilePath);
    }
}

Obviously, the production environment will have an empty or non-existent appSettings.json file, and all values will be derived from the key store. Or alternatively, you use the appSettings.json file in your production environment, but just for configuration values that do not contain secrets.