How to: Implement Azure Key Vault Implementation in ASP.NET Core Site Hosted on On-Premise Azure VM
Azure Key Vault Implementation in ASP.NET Core site hosted on On-Premise Azure VM
Introduction
Azure Key Vault Implementation in ASP.NET core site hosted on On-Premise Azure VM.
This article covers how to implement key vault part of application design, architecture and development, the cloud configurations to consume key vault is out of this topic coverage, however the required essential information is provided part of pre-requistes to consume key vault for on-premise web app setup.
Background
When keyvault is needed for storing client secrets, credentials for host VMS in cloud specially Azure.
Pre-requistes
- Create Azure Key Vault as per https://docs.microsoft.com/en-us/azure/key-vault/quick-create-portal
- Ensure the key vaults are created in the same vnet’s so to communicate without any issues, for keyvaults in any other vnets ( due to security), please do ensure, you add/allow those networks or any firewall settings to access the keyvault as part of the keyvault settings as shown below:
- If you are unsure of the settings required, talk to your internal cloud network engineer to get this up and running.
- Add the Service Principle of the website registered in AAD area of app registrations to the key vault Access Policies.
- Similarly add the VM which hosts the Website to the access policy of the key vault (the VM should be System Identified, enable it in the Identity Settings of the VM).
- All latest after 2.1 .NET Core projects have Azure Key Vault Package In-built.
Using the Code
Code to Implement Key Vault in ASP.NET Core Program.cs File
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((context, config) =>
{
var builder = config.Build();
var keyVaultEndpoint = builder["KeyVault:Vault"];
var azureServiceTokenProvider = new AzureServiceTokenProvider();
var keyVaultClient = new KeyVaultClient(
new KeyVaultClient.AuthenticationCallback(
azureServiceTokenProvider.KeyVaultTokenCallback)
);
config.AddAzureKeyVault(keyVaultEndpoint,keyVaultClient,
new DefaultKeyVaultSecretManager());
})
.UseStartup<Startup>()
.Build();
Sample environment based appSettings file which has reference to say example crm, social logins, custom password, etc.
"KeyVault": {
"Vault": "https://nameofkeyvault.vault.azure.net/",
//"ClientId": "myclientid",
//"ClientSecret": "myclientsecret",
"Authentication": {
"Microsoft": {
"ApplicationId": "appidkey",
"Password": "nameofpasswordkeyvault"
},
"Google": {
"ClientId": "appidkey",
"ClientSecret": "nameofpasswordkeyvault"
},
"Facebook": {
"AppId": "appidkey",
"AppSecret": "nameofpasswordkeyvault"
},
"LinkedIn": {
"AppId": "appidkey",
"AppSecret": "nameofpasswordkeyvault"
}
},
"Xrm": {
"Configuration": {
"SVCEndpoint": "https://client.myblog.com:443/OnlineService.svc",
"ServiceUrl": "http://client.myblog.com/api/data/v8.0/",
"ClientId": "",
"Domain": "myblog.com",
"UserName": "crm",
"Password": "crm",
"IsWebAPIEndpoint": true,
"IsSVCEndpoint": true
}
}
}
- Access the key vault values via Startup.cs or any other classes if referencing any external login or any other dependencies like API, etc.
Example for Startup.cs:
//AUTHENTICATION
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(options => { options.LoginPath = "/Account/Login/"; })
.AddMicrosoftAccount(microsoftOptions =>
{
microsoftOptions.ClientId =
Configuration["KeyVault:Authentication:Microsoft:ApplicationId"];
var password= Configuration["KeyVault:Authentication:Microsoft:Password"];
microsoftOptions.ClientSecret = Configuration[password];
})
.AddGoogle(googleOptions =>
{
googleOptions.ClientId = Configuration["KeyVault:Authentication:Google:ClientId"];
var clientSecret= Configuration["KeyVault:Authentication:Google:ClientSecret"];
googleOptions.ClientSecret = Configuration[clientSecret];
})
.AddFacebook(facebookOptions =>
{
facebookOptions.AppId = Configuration["KeyVault:Authentication:Facebook:AppId"];
var appSecret= Configuration["KeyVault:Authentication:Facebook:AppSecret"];
facebookOptions.AppSecret = Configuration[appSecret];
});
Inside any controller or any class file, the configuration values can be accessed via the IOptions
Configuration interface.
In controller via Constructor injection like below:
public class SampleController : Controller
{
#region Variables
private readonly IConfiguration _configuration;
#endregion #region constructors
public SampleController(IConfiguration configuration)
{
_configuration = configuration;
}
#Methods
public async Task<ActionResult> SampleMethod(string fileUri, string fileName)
{
try
{
if (User.Identity.IsAuthenticated)
{
//Get the email and load the person Identity
//var loggedInEmail = "###@i.com";
var vault = _configuration.GetSection
("KeyVault:Xrm: COnfiguration:UserName"); // Get the value
// from key vault config key in appsettings which
// gets from key vault.
}
}
catch (Exception ex)
{
ViewData["message"] = ex.Message;
View("~/Views/Shared/Error.cshtml");
}
return null;
}
Known Issues
- There will be known issues for projects after 2.1 due to the below package upgrade required.
Microsoft.Azure.Services.AppAuthentication v1.3.1
is required, add the nuget and publish. - Please add this package and build, publish to the website on the VM to test, for any issue, enable logging in web.config (
stdout ~ true
)