Skip to content

Latest commit

 

History

History
298 lines (202 loc) · 16.3 KB

File metadata and controls

298 lines (202 loc) · 16.3 KB

How to use certificates instead of secrets in your application(s)

Microsoft identity platform supports two types of authentication for confidential client applications: password-based authentication (i.e. client secret) and certificate-based authentication. For a higher level of security, we recommend using a certificate (instead of a client secret) as a credential in your confidential client applications.

In production, you should purchase a certificate signed by a well-known certificate authority, and use Azure Key Vault to manage certificate access and lifetime for you. For testing purposes, follow the steps below to create a self-signed certificate and configure your apps to authenticate with certificates.

Using certificates

ℹ️ Expand this to use automation

⚠️ Make sure you have OpenSSL installed on your machine. After installation, you may need to start a new command line instance for the openssl command to be available on system path.

choco install openssl

Alternatively, download and build OpenSSL for your OS following the guide at github.com/openssl. If you like to skip building and get a binary distributable from the community instead, check the OpenSSL Wiki: Binaries page.

  1. While inside AppCreationScripts folder, open a terminal.

  2. Run the Cleanup-withCertCertificates.ps1 script to delete any existing app registrations and certificates for the sample.

    .\Cleanup-withCertCertificates.ps1
  1. Run the Configure-withCertCertificates.ps1 script to re-create the App Registration. The script will also create .pfx file(s) (e.g. msal-node-webapp.pfx) that you can upload to Key Vault later. When asked about a password, do remember it - you will need the password when uploading the certificate.
    .\Configure-withCertCertificates.ps1
  1. Proceed to step 3 to configure application settings.

If you plan to deploy your app(s) to Azure App Service afterwards, we recommend Azure Managed Identity to completely eliminate secrets, certificates, connection strings and etc. from your source code. See Using Managed Identity below for more.

Create a self-signed certificate

You can skip this step if you already have a valid self-signed certificate at hand.

Create self-signed certificate on local machine

If you wish to generate a new self-signed certificate yourself, follow the steps below.

Click here to use OpenSSL

Download and build OpenSSL for your OS following the guide at github.com/openssl. If you like to skip building and get a binary distributable from the community instead, check the OpenSSL Wiki: Binaries page. Afterwards, add the path to OpenSSL to your environment variables so that you can call it from anywhere.

Type the following in a terminal. The files will be generated in the terminals current directory.

openssl req -x509 -newkey rsa:2048 -keyout msal-node-webapp.key -out msal-node-webapp.cer -subj "/CN=msal-node-webapp" -nodes

Generating a RSA private key
.........................................................
writing new private key to 'msal-node-webapp.key'

The following files should be generated: msal-node-webapp.key, msal-node-webapp.cer

If you need, you can generate a msal-node-webapp.pfx (certificate + private key combination) with the command below:

openssl pkcs12 -export -out CertificateName.pfx -inkey msal-node-webapp.key -in msal-node-webapp.cer

Enter an export password when prompted and make a note of it. The following file should be generated: msal-node-webapp.pfx.

Proceed to Step 2.

ℹ️ If you wish so, you can upload your locally generated self-signed certificate to Azure Key Vault later on. See: Import a certificate in Azure Key Vault

Create self-signed certificate on Key Vault

You can use Azure Key Vault to generate a self-signed certificate for you. Doing so will have the additional benefits of assigning a partner Certificate Authority (CA) and automating certificate rotation.

ℹ️ Azure Key Vault can export certificates and private keys in pem format (see: Export stored certificates), if Content Type was chosen as pem during certificate generation (see: Create a certificate in Key Vault). If for some reason this is not the case, OpenSSL can be used for conversions.

cat msal-node-webapp.crt msal-node-webapp.key > msal-node-webapp.pem ## if powershell: Get-Content msal-node-webapp.crt, msal-node-webapp.key | Set-Content msal-node-webapp.pem
openssl pkcs12 -in msal-node-webapp.pfx -out msal-node-webapp.pem
Click here to use Microsoft Entra admin center

Follow the guide: Set and retrieve a certificate from Azure Key Vault using the Microsoft Entra admin center

Afterwards, proceed to Step 2.

Click here to use Powershell

Follow the guide: Set and retrieve a certificate from Azure Key Vault using Azure PowerShell

Afterwards, proceed to Step 2.

Configure a Microsoft Entra app registration to use a certificate

Now you must associate your Microsoft Entra app registration with the certificate you will use in your application.

ℹ️ If you have the certificate locally available, you can follow the steps below. If your certificate(s) is on Azure Key Vault, you must first export and download them to your computer, and delete the local copy after following the steps below. See: Export certificates from Azure Key Vault

  1. Navigate to Microsoft Entra admin center and select your Microsoft Entra app registration.
  2. Select Certificates & secrets blade on the left.
  3. Click on Upload certificate and select the certificate file to upload (e.g. msal-node-webapp).
  4. Click Add. Once the certificate is uploaded, the thumbprint, start date, and expiration values are displayed. Record the thumbprint value as you will make use of it later in your app's configuration file.

For more information, see: Register your certificate with the Microsoft identity platform

Proceed to Step 3

Configure your app(s) to use a certificate

Finally, you need to modify the app's configuration files.

Using an existing certificate from local machine

Perform the steps below for the client app (msal-node-webapp)

  1. Open the file where MSAL is initialized (e.g. 1-Authentication\1-sign-in\App\app.js).
  2. Comment out the line for clientSecret:
    const authConfig = {
        auth: {
            clientId: "YOUR_CLIENT_ID",
            authority: "https://login.microsoftonline.com/YOUR_TENANT_ID",
            //clientSecret: "YOUR_CLIENT_SECRET"
        }
    };
  1. Un-comment the lines for clientCertificate and replace the default values:
    const fs = require('fs'); // import the fs module for reading the key file

    const authConfig = {
        auth: {
            clientId: "YOUR_CLIENT_ID",
            authority: "https://login.microsoftonline.com/YOUR_TENANT_ID",
            //clientSecret: "YOUR_CLIENT_SECRET"
            clientCertificate: {
                thumbprint: "YOUR_CERT_THUMBPRINT", // replace with thumbprint obtained during step 2 above
                privateKey: fs.readFileSync('PATH_TO_YOUR_PRIVATE_KEY_FILE'), // e.g. c:/Users/diego/Desktop/example.key
            }
        }
    };

ℹ️ For more details, see: initializing-msal-node-with-certificates

You can now start the application as instructed in the README.

Using an existing certificate from Key Vault

Perform the steps below for the client app (msal-node-webapp)

  1. Open the file where MSAL is initialized (e.g. 1-Authentication\1-sign-in\App\app.js).
  2. Comment out the line for clientSecret:
    const authConfig = {
        auth: {
            clientId: "YOUR_CLIENT_ID",
            authority: "https://login.microsoftonline.com/YOUR_TENANT_ID",
            //clientSecret: "YOUR_CLIENT_SECRET"
        }
    };
  1. Install Azure CLI. Then, type the following to sign-in:
    az login --tenant YOUR_TENANT_ID
  1. Install the required NPM packages:
    npm install --save @azure/identity @azure/keyvault-certificates @azure/keyvault-secrets
  1. Update the code as shown below:
    const identity = require("@azure/identity");
    const keyvaultCert = require("@azure/keyvault-certificates");
    const keyvaultSecret = require('@azure/keyvault-secrets');

    const KV_URL = process.env["KEY_VAULT_URL"] || "ENTER_YOUR_KEY_VAULT_URL"
    const CERTIFICATE_NAME = process.env["CERTIFICATE_NAME"] || "ENTER_THE_NAME_OF_YOUR_CERTIFICATE_ON_KEY_VAULT";

    // Initialize Azure SDKs
    const credential = new identity.DefaultAzureCredential();
    const certClient = new keyvaultCert.CertificateClient(KV_URL, credential);
    const secretClient = new keyvaultSecret.SecretClient(KV_URL, credential);

    async function main() {

        // Grab the certificate thumbprint
        const certResponse = await certClient.getCertificate(CERTIFICATE_NAME).catch(err => console.log(err));
        const thumbprint = certResponse.properties.x509Thumbprint.toString('hex')

        // When you upload a certificate to Key Vault, a secret containing your private key is automatically created
        const secretResponse = await secretClient.getSecret(CERTIFICATE_NAME).catch(err => console.log(err));;

        // secretResponse contains both public and private key, but we only need the private key
        const privateKey = secretResponse.value.split('-----BEGIN CERTIFICATE-----\n')[0]

        const authConfig = {
            auth: {
                clientId: "YOUR_CLIENT_ID",
                authority: "https://login.microsoftonline.com/YOUR_TENANT_ID",
                //clientSecret: "YOUR_CLIENT_SECRET",
                clientCertificate: {
                    thumbprint: thumbprint
                    privateKey: privateKey
                }
            }
        };

        // Pass config object to msal-node...
    }

    main();

ℹ️ For more details, see: Get certificate from your Key Vault in Node.js

You can now start the application as instructed in the README.

Using Managed Identity

Once you deploy your app(s) to Azure App Service, you can assign a managed identity to it for accessing Azure Key Vault using its own identity. This allows you to eliminate the all secrets, certificates, connection strings and etc. from your source code.

Create a system-assigned identity

  1. Navigate to Microsoft Entra admin center and select the Azure App Service.
  2. Find and select the App Service instance you've created previously.
  3. On App Service portal, select Identity.
  4. Within the System assigned tab, switch Status to On. Click Save.

For more information, see Add a system-assigned identity

Grant access to Key Vault

Now that your app deployed to App Service has a managed identity, in this step you grant it access to your key vault.

  1. Go to the Microsoft Entra admin center and search for your Key Vault.
  2. Select Overview > Access policies blade on the left.
  3. Click on Add Access Policy > Certificate permissions > Get
  4. Click on Add Access Policy > Secret permissions > Get
  5. Click on Select Principal, add your account and pre-created system-assigned identity.
  6. Click on OK to add the new Access Policy, then click Save to save the Access Policy.

For more information, see Use Key Vault from App Service with Azure Managed Identity

Add environment variables

Finally, you need to add environment variables to the App Service where you deployed your app.

⚠️ Make sure your application is able to read environment variables. Alternatively, you can hardcode the key vault URL and certificate name in your applications configuration file.

  1. In the Microsoft Entra admin center, search for and select App Service, and then select your app.
  2. Select Configuration blade on the left, then select New Application Settings.
  3. Add the following variables (key-value pairs):
    1. KEY_VAULT_URL: the URL of the key vault you've created, e.g. https://example.vault.azure.net
    2. CERTIFICATE_NAME: the name of the certificate you specified when importing it to key vault, e.g. ExampleCert

Wait for a few minutes for your changes on App Service to take effect. You should then be able to visit your published website and sign-in accordingly.

More information