In this article, I show how Azure Key Vault can be used with a non Azure application. An example of this, is a console application used for data migrations, or data seeding during release pipelines. This app could then read the secret connection strings from the Key Vault, and then do the app logic as required.
Code: https://github.com/damienbod/AspNetCoreBackChannelLogout
Posts in this series:
- OpenID Connect back-channel logout using Azure Redis Cache and IdentityServer4
- Using Azure Key Vault with ASP.NET Core and Azure App Services
- Deploying ASP.NET Core App Services using Azure Key Vault and Azure Resource Manager templates
- Using Azure Key Vault from a non-Azure App
Create a Key Vault
You can create an Azure Key Vault by following the Microsoft documentation here:
https://docs.microsoft.com/en-us/azure/key-vault/key-vault-get-started
Or using the Azure UI, you can create a Key Vault by clicking the “+ Create a Resource” blade and typing Key Vault in the search text input.
Fill out the inputs as required.
Now the Key Vault should be ready.
Create an Azure AD Application
To connect from a non Azure application, an Azure AD Application Registration needs to be added. Click Azure Active Directory, and then in the new blade App registrations (Preview). This will probably be renamed soon. Click the New registration.
In the new blade, Register a new application. Give it a name and save.
Wait a bit, and the AAD Application registration will be created. Save the Application (client) ID somewhere as this is required in the code.
Now a secret for the AAD Application registration needs to be created. Click the Certificates & secrets button, and then New client secret.
Configure the secret, give it a description and define how long it should remain active.
Save the secret somewhere, as this is required in the code, to access the Key Vault.
Configure the Azure Key Vault to allow the Azure AD Application
In the Azure Key Vault, the AAD Application registration needs to be given access rights.
Open the Key Vault, and click the Access policies. Then click the Add new button.
Select the AAD Application registration principle which was created before. You can find this, by entering the name. In this example, it was called standalone. Then give it the required permissions and save.
Also save when you re-enter to the Key Vault blade after clicking save.
Create your Standalone Application and use the Azure Key Vault
Now the application, which can be run anywhere, and use the Key Vault secrets, can be configured and created. In this example, a console application is created, which uses the Microsoft.AspNetCore.App and the Microsoft.Extensions.Configuration.AzureKeyVault.
You could also create a web application, or whatever. A console application could be used for example, to do migrations or data seeding in a build pipeline.
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework>netcoreapp2.2</TargetFramework> </PropertyGroup> <ItemGroup> <PackageReference Include="Microsoft.AspNetCore.App" Version="2.2.1" /> <PackageReference Include="Microsoft.Extensions.Configuration.AzureKeyVault" Version="2.2.0" /> </ItemGroup> <ItemGroup> <None Update="appsettings.json"> <CopyToOutputDirectory>Always</CopyToOutputDirectory> </None> </ItemGroup> </Project>
Now configure the application to use the Key Vault. This is done using the AddAzureKeyVault extension method, with the 3 parameters using the data from above; the DNS name of the Key vault, the AAD Application Registration Application ID, and the Secret.
var dnsNameKeyVault = _config["DNSNameKeyVault"]; if (!string.IsNullOrWhiteSpace(dnsNameKeyVault)) { configBuilder.AddAzureKeyVault($"{dnsNameKeyVault}", _config["AADAppRegistrationAppId"], _config["AADAppRegistrationAppSecret"]); _config = configBuilder.Build(); }
The program reads the configuration from the app settings, adds the services, and displays the Key Vault secret.
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using System; using System.IO; using System.Reflection; namespace ConsoleStandaloneUsingAzureSecrets { class Program { private static IConfigurationRoot _config; private static IServiceProvider _services; static void Main(string[] args) { Console.WriteLine("Console APP using Azure Key Vault"); GetConfigurationsForEnvironment(); SetupServices(); // read config value var someSecret = _config["SomeSecret"]; Console.WriteLine($"Read from key vault: {someSecret}"); Console.ReadLine(); } private static void SetupServices() { var serviceCollection = new ServiceCollection(); // Do migration, seeding logic or whatever _services = serviceCollection.BuildServiceProvider(); } private static void GetConfigurationsForEnvironment() { var environmentName = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT"); var location = Assembly.GetEntryAssembly().Location; var directory = Path.GetDirectoryName(location); Console.WriteLine($"{directory}{Path.DirectorySeparatorChar}appsettings.json"); Console.WriteLine($"{environmentName}"); var configBuilder = new ConfigurationBuilder() .AddJsonFile($"{directory}{Path.DirectorySeparatorChar}appsettings.json", false, true) .AddJsonFile($"{directory}{Path.DirectorySeparatorChar}appsettings.{environmentName}.json", true, true) .AddEnvironmentVariables(); _config = configBuilder.Build(); var dnsNameKeyVault = _config["DNSNameKeyVault"]; if (!string.IsNullOrWhiteSpace(dnsNameKeyVault)) { configBuilder.AddAzureKeyVault($"{dnsNameKeyVault}", _config["AADAppRegistrationAppId"], _config["AADAppRegistrationAppSecret"]); _config = configBuilder.Build(); } } } }
The appsettings.json file contains the values used above. If this was a real application, you should not save the secret to the app settings. These values could be left empty, and set during a deployment, for example using Azure Devops. Or in a web application, you could use user secrets.
Thes values here are no longer valid. If you want to run the code locally, these need to be set to correct values.
{ "DNSNameKeyVault": "https://standalone-kv.vault.azure.net/", "AADAppRegistrationAppId": "7faea48d-141e-41f9-9d9e-4ec9fd93ead0", "AADAppRegistrationAppSecret": "OWs6u2hY{F$UjXB5j7l&&DeNk9+$at{y/!pg!1Xh8MB@L", "SomeSecret": "DEV_VALUE" }
You must also configure a secret in the key Vault which will be read in the standalone
Running the Application
Using the Key vault values:
When the application is started, with correct Key Vault and AAD application registration values, the configuration is read from the Key Vault.
If the DNSNameKeyVault property is not set, the development settings in the appsettings.json is used.
Links
https://docs.microsoft.com/en-us/azure/key-vault/key-vault-developers-guide
https://stackoverflow.com/questions/40025598/azure-key-vault-access-denied
https://cmatskas.com/securing-asp-net-core-application-settings-using-azure-key-vault/
https://github.com/jayendranarumugam/DemoSecrets/tree/master/DemoSecrets
https://docs.microsoft.com/en-us/cli/azure/install-azure-cli-windows?view=azure-cli-latest
https://docs.microsoft.com/en-us/azure/key-vault/key-vault-developers-guide
https://stackoverflow.com/questions/40025598/azure-key-vault-access-denied
https://cmatskas.com/securing-asp-net-core-application-settings-using-azure-key-vault/
https://github.com/jayendranarumugam/DemoSecrets/tree/master/DemoSecrets
https://docs.microsoft.com/en-us/cli/azure/install-azure-cli-windows?view=azure-cli-latest