Telerik blogs

Certificates are often the best way to secure your application (you can use with everything from App Registrations to Web Services). Here’s everything you need to know to integrate certificates stored in your Azure Key Vault into your application.

In an earlier post, Coding Azure 12: Configuring an Azure Key Vault and Adding Secrets, I described how to set up a Key Vault and store a text “secret” in it. This post is about storing and retrieving certificates from your Key Vault.

There are several reasons that your application might need to retrieve a certificate from a Key Vault. In this post (while covering both how to add a certificate to a Key Vault in the Azure Portal and the code to retrieve credentials in a server-side application), I’m going to look at two specific use cases. Those two cases are using a certificate as credentials required to:

  • Claim an App Registration
  • To access a Web Service

Before showing that, however, it’s worth pointing out that you don’t have to use a Key Vault for an application running in an App Service. You can also store certificates in your App Service’s certificates collection.

An App Service’s certificates collection will let you store certificates that have only public keys (i.e. a *.cer file), certificates with public and private keys (*.pfx, *.per files), and Managed Keys (which are certificates that are automatically renewed for you). However, using the App Service’s certificates collection requires a paid App Service Plan and, since I’m using free services as much as possible in my case study, I won’t take advantage of that feature.

Besides, if I used the App Service’s certificates, I wouldn’t have a reason to discuss retrieving certificates from the Key Vault in an ASP.NET Core 8 application.

One last note: The reason you’re storing confidential data in a Key Vault is to restrict its access to only two things—a Key Vault administrator (who adds the confidential data to the vault) and your application (which retrieves the confidential data at run time). I covered how to restrict your vault access to your application in an earlier post.

Creating the Certificate

Your first step is, of course, to create a certificate. For both of my use cases, I’m creating a certificate that will only be used internally: by my application, my App Registration and my Web Service. On that basis, rather than use a certificate from a signing authority (which would be required if I was accessing an external Web Service), I can use a “self-signed certificate” that you can generate.

You can generate a self-signed certificate in two ways: have the Key Vault generate a certificate for you or upload an existing certificate (which is what you’d have to use if you were working with a certificate from a signing authority).

Generating a Certificate in the Key Vault

To have your Key Vault generate a certificate:

  1. Surf to your Key Vault in the Azure Portal.
  2. In the menu on the left, drill down through the Objects choice and select Certificates to open a new page on the right.
  3. At the left end of the menu across the top of the page, click on the + Generate/Import menu choice.
  4. Leave the dropdown list at the top set to Generate.
  5. In the Certificate Name textbox below that dropdown, enter a name that will identify your certificate (for a certificate that’s acting as credentials to either an App Registration or a Web Service, I might used the name ServerCredentials).
  6. In the Subject textbox below that, enter a subject that describes your certificate and prefix it with “CN=” (I used CN=ServerCredentials).
  7. Accept the rest of the defaults (this will cause your self-signed certificate to renew automatically roughly every nine and a half months).
  8. Click the Create button at the bottom of the page to generate your certificate in your vault and return to the list of certificates in your vault.

It may take a few moments for your certificate to finish generating and to be added. During that time, it will appear in the “In progress, pending, or cancelled” section of your certificate’s list with a status of disabled. You can use the Refresh choice in the menu across the top of the page to update your list while you wait for the process to complete.

Saving the Certificate Locally

After your certificate is generated, you may want to have a local copy of it (if you’re going to use this certificate as credentials for claiming an App Registration, you will need a local copy). To create a copy of your certificate in a file:

  1. In the list of certificates in the Key Vault, click on your certificate to open its Overview page that lists all the versions of your certificate. (Remember: When you update an item in the Key Vault, you actually add a new version of the item.)
  2. In the Overview page, click on the version of your certificate that you want to export (probably the current version, which is at the top of the list).
  3. In the page for the selected version of your certificate, from the right end of the menu across the top of the page, click on the Download in format choice to pick up the kind of certificate you want.

Choosing your format: If you only need a certificate with a public key (for example, as credentials for an App Service or Web Service), use the CER format. Use the PFX format if you need a certificate with both a public and a private key (a certificate with a private key should never be shared outside of your organization).

  1. After you click on your download choice, you’ll get an “Are you sure?” dialog. Click on the dialog’s Download button.
  2. In the Save As dialog that appears, surf to the folder where you want to keep your certificate and click the Save button to save your certificate in a local file.

You may also want to add your certificate to your local certificate store, rather than keep it on your hard disk. To save your certificate in your certificate store, first open a Windows command window, then enter certmgr and press the Enter key to open the Certificate Manager dialog.

In the treeview on the left of the Certificate Manager dialog, drill down through the Personal node and right-click on the Certificates node. From the All Tasks menu, select Import to start the Certificate Import Wizard. Work your way through the wizard, using the Browse button on the wizard’s second page to surf to your certificate file and add it to your store.

Uploading an Existing Certificate

Rather than create a new certificate, you might choose to add an already existing certificate to your vault. That certificate might be in your certificate store or may just be a file on your hard disk.

Note: To demonstrate working with an existing certificate, I generated a self-signed certificate using the following PowerShell command. If decide to create your own, you might want to change the name in the Subject parameter:

New-SelfSignedCertificate -Subject CN=ServerCredentials `
                                                         -CertStoreLocation 'Cert:\CurrentUser\My'

Extract a Certificate from Your Computer’s Certificate Store

If you want to use a certificate from your certificate store, then you’ll first need to export the certificate from your store. Start by opening a Windows command window then entering certmgr and pressing the Enter key to open the Certificate Manager dialog. In the treeview on the left of the dialog, drill down through the Personal node to Certificates to display a list of certificates already in your store in the pane on the right—your newly created certificate will be listed there (in my case, ServerCredentials).

Next right-click on that certificate and, from the popup menu, select All Tasks | Export to start the certificate manager’s Export wizard. Work through the wizard, including:

  1. Selecting Yes, export the private key on the wizard’s second screen (the Key Vault will only import certificates with a public and a private key)
  2. Providing a password on the wizard’s third page (and make a note of the password—you’ll need it later)
  3. Entering a file name (ServerCredentials) on the wizard’s fourth page
  4. Clicking the Finish button at the end of the wizard to export your certificate into a .pfx file

Importing a Certificate File into the Key Vault

To upload a certificate file into your vault (in my case, a file called ServerCredentials.pfx), you’ll need both the certificate file and the password that was used when saving the file. With those in hand, the steps to import the file are:

  1. Surf to your Key Vault in the Azure Portal.
  2. In the menu on the left of the Key Vault, expand the Objects node and select Certificates to display, on the right, the list of certificates already in the vault.
  3. At the left end of the menu across the top of the new page, click on the + Generate/Import choice to open a new page.
  4. In the new page, set the Upload options dropdown list at the top of the page to Import to import your certificate.
  5. In the Certificate Name textbox below that dropdown, enter a name that will identify your certificate. (I used the name of the file I’m importing but without its extension: ServerCredentials.)
  6. In the Upload Certificate File file-browser below that, browse to the certificate file that you want to import and select it.
  7. Click the Open button to import your file and add it to the Key Vault.
  8. In the Password textbox below the filename, enter the password for the certificate.
  9. Click the Create button at the bottom of the page to add your uploaded certificate to your vault.

You’ll be returned to the list of certificates in your vault with your new certificate listed under the list’s Completed heading.

Using a Certificate as Credentials for an App Registration

Up until this post, I’ve only required my applications to provide a secret text string to claim an App Registration (along with the permissions that the registration grants). A more secure solution is to require an application to provide a certificate as its credentials for claiming an App Registration. Now that I have a certificate securely stored in a Key Vault (and a vault that only my application is able to access), I’m going to switch my App Registration over to requiring that certificate.

Setting a Certificate as the Credentials Required by an App Registration

To have an App Registration require a certificate as credentials to claim the registration:

  1. First, surf to App Registrations in the Azure Portal.
  2. From the list of App Registrations that’s displayed, click on the App Registration that you want to have require a certificate. (I picked the registration for my server-side ASP.NET frontend that I created in an earlier post, Coding Azure 9b: Securing a Server-Side Frontend to a Web Service: WarehouseMgmtRegFrontEndASPNETReg.)
  3. In the menu on the left, expand the Manage node and select the Certificates & secrets choice to open a page on the right.
  4. In the page on the right, click on the Certificates tab.
  5. Click on the Upload certificate link above the list of certificates to open a panel on the right.
  6. Click on the blue button at the right end of the Upload a certificate (with… file-browser.
  7. In the Open dialog that appears, surf to the *.cer file that holds your certificate (ServerCredentials.cer, in my case).
  8. Select your certificate and click the Open button to upload your certificate. (You can, optionally, enter a description of what your certificate is being used for.)
  9. Click the Add button to close the panel and return to the list of certificates being used with your App Registration.

While you’re on this tab, if you previously set up this App Registration to use a secret as credentials then you should probably now open the App Registration’s Secrets tab and delete that secret.

Retrieving a Certificate to Use as Credentials for an App Registration

You’re now ready to retrieve an App Registration using a certification. First, you need to add a JSON object named AzureAd to your server-side application’s appsettings.json file with these properties:

  • Instance: A reference to your identity provider (for Entra Id, that’s "https://login.microsoftonline.com/")
  • Domain: The URL for your App Service (from your App Service’s Overview page)
  • TenantId: From your App Service’s Overview page
  • ClientId: From your App Service’s Overview page (also called Application Id)
  • CallbackPath: "/signin-oidc",
  • ClientCertificates: A JSON array

Each of the JSON objects in the ClientCertificates array must have these three properties (and you only need one):

  • SourceType: "KeyVault"
  • KeyVaultUrl: The URL for the Key Vault that holds your certificate (from the Key Vault’s Overview page)
  • KeyVaultCertificateName: The name of the item in your Key Vault’s Certificates section that holds the certificate required by the App Registration

A typical example would look like this:

  "AzureAd": {
    "Instance": "https://login.microsoftonline.com/",
    "Domain": "warehousemgmtfrontendaspnet.azurewebsites.net",
    "TenantId": "e98…-…-…-…-…a461",
    "ClientId":"80e…-…-…-…-…f3b",
    "CallbackPath": "/signin-oidc",
    "ClientCertificates": [
      {
        "SourceType": "KeyVault",
        "KeyVaultUrl": "https://warehousemgmtvault.vault.azure.net/",
        "KeyVaultCertificateName": "ServerCredentials"
      }
    ]
  },

The code that you need to claim your App Registration and get the access tokens it supplies is the same as what you would use if your application was retrieving an App Registration protected with a text secret (see Coding Azure 9a: Authorizing Your Frontend Client-Side App to Access a Web Service). In your Program.cs file, for example, you need this code to retrieve any access tokens from the registration and add them to an internal cache:

builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
    .AddMicrosoftIdentityWebApp(builder.Configuration)
    .EnableTokenAcquisitionToCallDownstreamApi()
    .AddInMemoryTokenCaches();

And you need this code in your application to retrieve the token:

string accessToken = await tokenAcquisition.GetAccessTokenForAppAsync(
    "api://abd…-…-…-…-…a0b6/.default",
    tenant: config["AzureAd:TenantId"]);       

Retrieving a Certificate

You might also need to retrieve a certificate for other purposes—for example, to use as the credentials for calling a Web Service.

The first step in retrieving your certificate is to install the Azure.Security.KeyVault.Certificates NuGet package. With that package installed, you can retrieve your certificate by creating a CertificateClient object, passing a Uri object holding the URL for your Key Vault (available from your Key Vault’s Overview page) and a DefaultAzureCredential object.

Once you’ve created a CertificateClient, you can use its DownloadCertificate method to retrieve an Azure.Response object that has a Value property. That property, in turn, has Cer property which you can turn into an X509Certificate2 using the X509CertificateLoader’s static LoadCertificate property.

Typical code to do all that might look like this:

Uri kvu = new Uri("https://warehousemgmtvault.vault.azure.net/");
CertificateClient cc = new CertificateClient(
        kvu,
        new DefaultAzureCredential());
Azure.Response<KeyVaultCertificateWithPolicy> ar = cc.GetCertificate("FrontendServerRegCredentialsGenerated");
X509Certificate2 cert = X509CertificateLoader.LoadCertificate(ar.Value.Cer);
logger.LogInformation("Certification subject: " + cert.Subject);

How you use that certificate will vary from one use case to another. For my case study, to use it as credentials with an HttpClient to call a Web Service, you need to first create an HttpClientHandler object. Once you’ve done that, you can add your certificate to the handler’s ClientCertificates collection and then pass the handler to your HttpClient object when you create it. Typical code will look like this:

HttpClientHandler chc = new HttpClientHandler();
chc.ClientCertificates.Add(cert);
HttpClient hc = new HttpClient(chc); 
HttpResponseMessage resp = await hc.GetAsync("<Web service URL");

Next Steps

Because Key Vaults are Microsoft’s tool for managing certificates in the cloud, there’s a lot more to say about managing certificates over the life of your application (setting a certificate policy to manage rotating your certificate and notifying parties when certificates need to be rotated, for example).

But, because I’m only interested in what’s required to get your application up and running, I’m moving on to my next topic: Accessing a Key Vault from a client-side app.


Peter Vogel
About the Author

Peter Vogel

Peter Vogel is both the author of the Coding Azure series and the instructor for Coding Azure in the Classroom. Peter’s company provides full-stack development from UX design through object modeling to database design. Peter holds multiple certifications in Azure administration, architecture, development and security and is a Microsoft Certified Trainer.

Related Posts

Comments

Comments are disabled in preview mode.