You are currently viewing Service principal and certificate with Azure key vault

Service principal and certificate with Azure key vault

In last article, we have seen how to access the Azure key vault using service principal.

Before we begin

You may want to go through some of the previous articles in this series. Below blog posts will guide you to create a key vault, add secrets to it and then access it from the .NET Core web application.

Now, you have a web application that accesses secrets from key vault. This web application is hosted as Azure web app which is probably using managed identity to access the key vault.

FYI – The web application allows user to upload documents. These documents are then uploaded to storage account. The credentials of storage account are stored in key vault.

If you have followed all steps from last blog article in the above list, then you will have this app service running. It is also using service principal. But it is using client secret authentication type and not certificates. In this article, we will have a look at how certificates can be used with service principal.

Plan of Action

As we already know, there are two ways to create service principal – by using CLI or by registering application in Azure AD.

In this article, we will register application in Azure AD, which will automatically generate service principal for our application. This service principal would be used by our .NET Core web application to access key vault.

We are going to perform below steps:

  • Register web application which will create service principal for the application
  • Add certificate which can be used for app authentication
  • Add access policy in key vault, which will allow access to newly created service principal
  • Modify .NET Core web application to use new connection string which uses service principal and certificate to connect to key vault

Sit tight and let’s get into action…!

App Registration

Refer my previous blog post to know the steps for new app registration.

In Azure portal, go to Azure AD and open the app registration which we just now created.

On the overview panel, Application (Client) ID and Directory (tenant) ID would be shown. Note them down as they would be required in our application.

Certificates

Ideally, certificates are bought from the certificate authority for production scenarios.

For this demo, we are going to create a self-signed certificate. Note that self-signed certificates are recommended only for testing scenarios.

Create self-signed certificate

Open PowerShell prompt and run New-SelfSignedCertificate with the following parameters to create a self-signed certificate in the user certificate store on your computer:

$cert=New-SelfSignedCertificate Subject "CN=KeyVaultDemoCert" CertStoreLocation "Cert:\CurrentUser\My" KeyExportPolicy Exportable KeySpec Signature
view raw Certificate.ps1 hosted with ❤ by GitHub

Export .cer certificate

Export this certificate to a file using the Manage User Certificate MMC snap-in accessible from the Windows Control Panel.

Export Certificates using Certificates Console Current User
Export Certificates using Certificates Console Current User
  1. Select Run from the Start menu and enter certmgr.msc and hit OK button. The Certificate Manager tool for the current user appears.
  2. To view your certificates, under Certificates – Current User in the left pane, expand the Personal directory.
  3. Right-click on the cert you created, select All tasks->Export.
  4. Follow the Certificate Export wizard. Do not export the private key, and export to a .CER file.

Upload certificate

Login to Azure portal and select Azure Active Directory from the left navigation. Select App registrations from the left side navigation of Azure AD menu and then select the appropriate app from the list to open it.

Then select Certificates and secrets menu from the left navigation and click on Upload certificate button.

Azure Portal: Upload certificate in app registration
Azure Portal: Upload certificate in app registration

Next a new panel will open which has a browse button. Click on browse button to select the exported .CER file and then click on OK.

When certificate is uploaded to Azure Portal, the thumbprint is shown. Note down this thumbprint as it would be required in the connection string.

Add access policy in key vault

Refer my previous blog post to know how the access policy can be added to allow the new app which is registered in Azure AD.

Application Configurations

Now, a new connection string should be passed to the constructor of AzureServiceTokenProvider . This new connection string should pass the certificate identity to Azure AD to prove identity of the application, instead of client secret.

There are two options if certificate authentication is used.

Thumbprint

One of the formats uses uses thumbprint. If you want to use thumbprint, the thumbprint is shown after uploading the certificate in Azure Portal. User this thumbprint in connection string.

RunAs=App;AppId={ClientId};TenantId={TenantId};CertificateThumbprint={Thumbprint};CertificateStoreLocation={LocalMachine or CurrentUser};

Subject

The other option is to use a format which uses subject of certificate.

If you want to use this variant of connection string, the subject can be found in the PowerShell command which you executed for creating the self-signed certificate. In above command, we have used CN=KeyVaultDemoCert,

RunAs=App;AppId={ClientId};TenantId={TenantId};CertificateSubjectName={Subject};CertificateStoreLocation={LocalMachine or CurrentUser}

It does not matter which form of connection string is used. Because both thumbprint and subject uniquely identify a certificate. We will use certificate’s subject in connection string.

In our case, the certificate store is CurrentUser as the above PowerShell command creates and adds certificate to CurrentUser store.

Complete Code

Below code snippet shows the Program.cs file of the web application. Optionally, publish this app to Azure app service.

public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((context, config) =>
{
var keyVaultEndpoint = GetKeyVaultEndpoint();
if (!string.IsNullOrEmpty(keyVaultEndpoint))
{
// In below connection string, replace
// {ClientId} with actual GUID representing client id
// {TenantId} with tenant id of Azure AD
// {Thumbprint} with the subject of certificate
// StoreLocation is CurrentUser for our demo
var thumbprintConnString = "RunAs=App;AppId={ClientId};TenantId={TenantId};CertificateThumbprint={Thumbprint};CertificateStoreLocation={LocalMachine or CurrentUser};";
// In below connection string, replace
// {ClientId} with actual GUID representing client id
// {TenantId} with tenant id of Azure AD
// {Subject} with the subject of certificate
// StoreLocation is CurrentUser for our demo
var subjectConnString = "RunAs=App;AppId={ClientId};TenantId={TenantId};CertificateSubjectName={Subject};CertificateStoreLocation={LocalMachine or CurrentUser}";
var azureServiceTokenProvider = new AzureServiceTokenProvider(thumbprintConnString);
var keyVaultClient = new KeyVaultClient(
new KeyVaultClient.AuthenticationCallback(
azureServiceTokenProvider.KeyVaultTokenCallback));
config.AddAzureKeyVault(keyVaultEndpoint, keyVaultClient, new DefaultKeyVaultSecretManager());
}
})
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
private static string GetKeyVaultEndpoint() => "https://<<your-key-vault>&gt;.vault.azure.net";
}
view raw Program.cs hosted with ❤ by GitHub

Access Certificate from App Service

The PowerShell commands executed creates and adds certificate to CurrentUser store of your development machine.

But when you publish the application, the application runs on Azure. So, it will not have access to your dev machine. This section explains how to upload certificate so that Azure App Service can use it.

Export pfx certificate

  1. Select Run from the Start menu and enter certmgr.msc and hit OK button. The Certificate Manager tool for the current user appears.
  2. To view your certificates, under Certificates – Current User in the left pane, expand the Personal directory.
  3. Right-click on the cert you created, select All tasks->Export.
  4. Follow the Certificate Export wizard. Remember to select the Export the private key option and export to a .pfx file. While exporting pfx, the wizard will ask you to enter a password for .pfx file. Enter some password and remember it. We will need this password while uploading this file to Azure App Service.

Import pfx certificate

Go to Azure Portal and select the app service where the web application is published. Select Settings -> TLS/SSL settings from the left navigation.

Then select the Private Key Certificates (.pfx) tab from the new panel. Now click on Upload Certificate button. This will show new panel in which you can select the .pfx file and enter the associated password.

Azure Portal: Upload private key certificate
Azure Portal: Upload private key certificate

Configuration Setting

To access a certificate in your app code, add its thumbprint to the WEBSITE_LOAD_CERTIFICATES app setting on the Azure app service.

  • Value can be comma separated list of thumbprints of certificates which application needs access to
  • Or the value can also be *, meaning application can access all the certificates.

So in the Azure app service, select Configuration options inside Settings from left navigation of app service instance.

Then click on New application setting button. It will show a new panel as shown below. Enter the setting name and * in value box and then click on OK to close this new panel.

Azure Portal: Add application setting for making certificate accessible
Azure Portal: Add application setting for making certificate accessible

Do not forget to hit Save button which is on Configuration panel.

Run and Verify

Now if we browse application (either from visual studio or from app service), the application can upload the files to storage account. Thus, our configurations are correct and application is able to read them properly.

.NET Core application able to access key vault now
.NET Core application able to access key vault now

I hope you enjoyed the article. Let me know your thoughts.

Leave a Reply