Condividi tramite


Avvio rapido - Libreria client dei certificati di Azure Key Vault per JavaScript

Introduzione alla libreria client dei certificati di Azure Key Vault per JavaScript. Azure Key Vault è un servizio cloud che offre un archivio sicuro per i certificati. È possibile archiviare in modo sicuro chiavi, password, certificati e altri segreti. È possibile creare e gestire istanze di Azure Key Vault tramite il portale di Azure. Questa guida di avvio rapido descrive come creare, recuperare ed eliminare certificati da Azure Key Vault utilizzando la libreria client JavaScript.

Risorse per la libreria client di Key Vault:

Documentazione di riferimento sull'API | Codice sorgente della libreria | Pacchetto (npm)

Per altre informazioni su Key Vault e sui certificati, vedere:

Prerequisiti

Questa guida di avvio rapido presuppone che si usi l'interfaccia della riga di comando di Azure.

Accedere ad Azure

  1. Eseguire il comando login.

    az login
    

    Se l'interfaccia della riga di comando può aprire il browser predefinito, eseguirà questa operazione e caricherà una pagina di accesso di Azure.

    In caso contrario, aprire una pagina del browser all'indirizzo https://aka.ms/devicelogin e immettere il codice di autorizzazione visualizzato nel terminale.

  2. Accedere con le credenziali dell'account nel browser.

Creare una nuova applicazione Node.js

Creare un'applicazione Node.js che usa l'insieme di credenziali delle chiavi.

  1. In un terminale creare una cartella denominata key-vault-node-app e passare a tale cartella:

    mkdir key-vault-node-app && cd key-vault-node-app
    
  2. Inizializzare il progetto Node.js:

    npm init -y
    

Installare i pacchetti di Key Vault

  1. Usando il terminale, installare la libreria dei segreti di Azure Key Vault, @azure/keyvault-certificates, per Node.js.

    npm install @azure/keyvault-certificates
    
  2. Installare la libreria client di identità di Azure, @azure/identity, per eseguire l'autenticazione in un'istanza di Key Vault.

    npm install @azure/identity
    

Concedere l'accesso all'insieme di credenziali delle chiavi

Per ottenere le autorizzazioni per l’insieme di credenziali delle chiavi tramite il controllo degli accessi in base al ruolo (RBAC), assegnare un ruolo all’UPN (User Principal Name) usando il comando dell’interfaccia della riga di comando di Azure az role assignment create.

az role assignment create --role "Key Vault Certificate Officer" --assignee "<upn>" --scope "/subscriptions/<subscription-id>/resourceGroups/<resource-group-name>/providers/Microsoft.KeyVault/vaults/<your-unique-keyvault-name>"

Sostituire <upn>, <subscription-id>, <resource-group-name> e <your-unique-keyvault-name> con i valori effettivi. L'UPN in genere sarà nel formato di un indirizzo e-mail (ad esempio, username@domain.com).

Impostare le variabili di ambiente

Questa applicazione usa l'endpoint dell'insieme di credenziali delle chiavi come variabile di ambiente denominata KEY_VAULT_URL.

set KEY_VAULT_URL=<your-key-vault-endpoint>

Autenticare e creare un client

Le richieste dell'applicazione per la maggior parte dei servizi di Azure devono essere autorizzate. L'uso del metodo DefaultAzureCredential fornito dalla libreria client di Identità di Azure è l'approccio consigliato per l'implementazione di connessioni senza password ai servizi di Azure nel codice. DefaultAzureCredential supporta più metodi di autenticazione e determina il metodo da usare in fase di esecuzione. Questo approccio consente all'app di usare metodi di autenticazione diversi in ambienti diversi (locale e di produzione) senza implementare codice specifico dell'ambiente.

In questo avvio rapido, DefaultAzureCredential esegue l'autenticazione nell’insieme di credenziali delle chiavi usando le credenziali dell'utente di sviluppo locale connesso all'interfaccia della riga di comando di Azure. Quando l'applicazione viene distribuita in Azure, lo stesso codice DefaultAzureCredential può individuare e usare automaticamente un'identità gestita assegnata a un servizio app, a una macchina virtuale o ad altri servizi. Per altre informazioni, vedere Panoramica delle identità gestite.

In questo codice, l'endpoint dell'insieme di credenziali delle chiavi viene usato per creare il client. Il formato dell'endpoint è simile a https://<your-key-vault-name>.vault.azure.net, ma può cambiare per i cloud sovrani. Per altre informazioni sull'autenticazione nell'insieme di credenziali delle chiavi, vedere la Guida per sviluppatori.

Esempio di codice

Questo codice usa le classi e i metodi del certificato di Key Vault seguenti:

Configurare il framework dell'app

  • Creare un nuovo file di testo e incollare il codice seguente nel file index.js.

    const { CertificateClient, DefaultCertificatePolicy } = require("@azure/keyvault-certificates");
    const { DefaultAzureCredential } = require("@azure/identity");
    
    async function main() {
      // If you're using MSI, DefaultAzureCredential should "just work".
      // Otherwise, DefaultAzureCredential expects the following three environment variables:
      // - AZURE_TENANT_ID: The tenant ID in Azure Active Directory
      // - AZURE_CLIENT_ID: The application (client) ID registered in the AAD tenant
      // - AZURE_CLIENT_SECRET: The client secret for the registered application
      const credential = new DefaultAzureCredential();
    
      const keyVaultUrl = process.env["KEY_VAULT_URL"];
      if(!keyVaultUrl) throw new Error("KEY_VAULT_URL is empty");
    
      const client = new CertificateClient(keyVaultUrl, credential);
    
      const uniqueString = new Date().getTime();
      const certificateName = `cert${uniqueString}`;
    
      // Creating a self-signed certificate
      const createPoller = await client.beginCreateCertificate(
        certificateName,
        DefaultCertificatePolicy
      );
    
      const pendingCertificate = createPoller.getResult();
      console.log("Certificate: ", pendingCertificate);
    
      // To read a certificate with their policy:
      let certificateWithPolicy = await client.getCertificate(certificateName);
      // Note: It will always read the latest version of the certificate.
    
      console.log("Certificate with policy:", certificateWithPolicy);
    
      // To read a certificate from a specific version:
      const certificateFromVersion = await client.getCertificateVersion(
        certificateName,
        certificateWithPolicy.properties.version
      );
      // Note: It will not retrieve the certificate's policy.
      console.log("Certificate from a specific version:", certificateFromVersion);
    
      const updatedCertificate = await client.updateCertificateProperties(certificateName, "", {
        tags: {
          customTag: "value"
        }
      });
      console.log("Updated certificate:", updatedCertificate);
    
      // Updating the certificate's policy:
      await client.updateCertificatePolicy(certificateName, {
        issuerName: "Self",
        subject: "cn=MyOtherCert"
      });
      certificateWithPolicy = await client.getCertificate(certificateName);
      console.log("updatedCertificate certificate's policy:", certificateWithPolicy.policy);
    
      // delete certificate
      const deletePoller = await client.beginDeleteCertificate(certificateName);
      const deletedCertificate = await deletePoller.pollUntilDone();
      console.log("Recovery Id: ", deletedCertificate.recoveryId);
      console.log("Deleted Date: ", deletedCertificate.deletedOn);
      console.log("Scheduled Purge Date: ", deletedCertificate.scheduledPurgeDate);
    }
    
    main().catch((error) => {
      console.error("An error occurred:", error);
      process.exit(1);
    });
    

Eseguire l'applicazione di esempio

  1. Eseguire l'app:

    node index.js
    
  2. I metodi create e get restituiscono un oggetto JSON completo per il certificato:

    {
      "keyId": undefined,
      "secretId": undefined,
      "name": "YOUR-CERTIFICATE-NAME",
        "reuseKey": false,
        "keyCurveName": undefined,
        "exportable": true,
        "issuerName": 'Self',
        "certificateType": undefined,
        "certificateTransparency": undefined
      },
      "properties": {
        "createdOn": 2021-11-29T20:17:45.000Z,
        "updatedOn": 2021-11-29T20:17:45.000Z,
        "expiresOn": 2022-11-29T20:17:45.000Z,
        "id": "https://YOUR-KEY-VAULT-NAME-ENDPOINT/certificates/YOUR-CERTIFICATE-NAME/YOUR-CERTIFICATE-VERSION",
        "enabled": false,
        "notBefore": 2021-11-29T20:07:45.000Z,
        "recoveryLevel": "Recoverable+Purgeable",
        "name": "YOUR-CERTIFICATE-NAME",
        "vaultUrl": "https://YOUR-KEY-VAULT-NAME-ENDPOINT",
        "version": "YOUR-CERTIFICATE-VERSION",
        "tags": undefined,
        "x509Thumbprint": undefined,
        "recoverableDays": 90
      }
    }
    
  • Creare un nuovo file di testo e incollare il codice seguente nel file index.ts.

    import {
      CertificateClient,
      DefaultCertificatePolicy,
      KeyVaultCertificate,
      DeletedCertificate,
      CertificatePolicy,
      KeyVaultCertificateWithPolicy,
    } from "@azure/keyvault-certificates";
    import { DefaultAzureCredential } from "@azure/identity";
    import "dotenv/config";
    
    const credential = new DefaultAzureCredential();
    
    // Get Key Vault name from environment variables
    // such as `https://${keyVaultName}.vault.azure.net`
    const keyVaultUrl = process.env.KEY_VAULT_URL;
    if (!keyVaultUrl) throw new Error("KEY_VAULT_URL is empty");
    
    function printCertificate(
      certificate: KeyVaultCertificate | KeyVaultCertificateWithPolicy
    ): void {
      console.log("-- printCertificate ---------------------------");
    
      // if policy is defined, it's a KeyVaultCertificateWithPolicy
      if ((certificate as KeyVaultCertificateWithPolicy).policy) {
        const { name, properties, policy } =
          certificate as KeyVaultCertificateWithPolicy;
        const { createdOn, updatedOn, expiresOn, vaultUrl, version, tags } =
          properties;
        console.log("Certificate: ", {
          name,
          createdOn,
          updatedOn,
          expiresOn,
          vaultUrl,
          version,
        });
        console.log("Certificate Policy: ", policy);
        printObjectProperties(tags);
        return;
      } else {
        const { name, properties } = certificate;
        const { createdOn, updatedOn, expiresOn, vaultUrl, version, tags } =
          properties;
        console.log("Certificate: ", {
          name,
          createdOn,
          updatedOn,
          expiresOn,
          vaultUrl,
          version,
        });
        printObjectProperties(tags);
      }
    }
    // Object properties are tags and CertificatePolicy
    function printObjectProperties(obj: Record<string, any>): void {
      if (!obj) return;
    
      console.log("-- printObjectProperties ---------------------------");
    
      Object.entries(obj).forEach(([key, value]) => {
        if (key === "lifetimeActions") {
          console.log(`${key}: ${JSON.stringify(value)}`);
        } else {
          console.log(`${key}: ${value}`);
        }
      });
    }
    function printDeletedCertificate(deletedCertificate: DeletedCertificate): void {
      const { recoveryId, deletedOn, scheduledPurgeDate } = deletedCertificate;
      console.log("Deleted Certificate: ", {
        recoveryId,
        deletedOn,
        scheduledPurgeDate,
      });
    }
    async function main(): Promise<void> {
      // Create a new CertificateClient
      const client = new CertificateClient(keyVaultUrl, credential);
    
      // Create a unique certificate name
      const uniqueString = new Date().getTime().toString();
      const certificateName = `cert${uniqueString}`;
    
      // Creating a self-signed certificate
      const createPoller = await client.beginCreateCertificate(
        certificateName,
        DefaultCertificatePolicy
      );
    
      // Get the created certificate
      const pendingCertificate = await createPoller.getResult();
      printCertificate(pendingCertificate);
    
      // Get certificate by name
      let certificateWithPolicy = await client.getCertificate(certificateName);
      printCertificate(pendingCertificate);
    
      // Get certificate by version
      const certificateFromVersion = await client.getCertificateVersion(
        certificateName,
        certificateWithPolicy.properties.version!
      );
      printCertificate(certificateFromVersion);
    
      // Update properties of the certificate
      const updatedCertificate = await client.updateCertificateProperties(
        certificateName,
        certificateWithPolicy.properties.version!,
        {
          tags: {
            customTag: "my value",
          },
        }
      );
      printCertificate(updatedCertificate);
    
      // Updating the certificate's policy
      const certificatePolicy = await client.updateCertificatePolicy(
        certificateName,
        {
          issuerName: "Self",
          subject: "cn=MyOtherCert",
        }
      );
      printObjectProperties(certificatePolicy);
    
      // Get certificate again to see the updated policy
      certificateWithPolicy = await client.getCertificate(certificateName);
      printCertificate(certificateWithPolicy);
    
      // Delete certificate
      const deletePoller = await client.beginDeleteCertificate(certificateName);
      const deletedCertificate = await deletePoller.pollUntilDone();
      printDeletedCertificate(deletedCertificate);
    }
    
    main().catch((error) => {
      console.error("An error occurred:", error);
      process.exit(1);
    });
    

Eseguire l'applicazione di esempio

  1. Compilare l'app TypeScript:

    tsc
    
  2. Eseguire l'app:

    node index.js
    
  3. I metodi create e get restituiscono un oggetto JSON completo per il certificato:

    {
      "keyId": undefined,
      "secretId": undefined,
      "name": "YOUR-CERTIFICATE-NAME",
        "reuseKey": false,
        "keyCurveName": undefined,
        "exportable": true,
        "issuerName": 'Self',
        "certificateType": undefined,
        "certificateTransparency": undefined
      },
      "properties": {
        "createdOn": 2021-11-29T20:17:45.000Z,
        "updatedOn": 2021-11-29T20:17:45.000Z,
        "expiresOn": 2022-11-29T20:17:45.000Z,
        "id": "https://YOUR-KEY-VAULT-NAME-ENDPOINT/certificates/YOUR-CERTIFICATE-NAME/YOUR-CERTIFICATE-VERSION",
        "enabled": false,
        "notBefore": 2021-11-29T20:07:45.000Z,
        "recoveryLevel": "Recoverable+Purgeable",
        "name": "YOUR-CERTIFICATE-NAME",
        "vaultUrl": "https://YOUR-KEY-VAULT-NAME-ENDPOINT",
        "version": "YOUR-CERTIFICATE-VERSION",
        "tags": undefined,
        "x509Thumbprint": undefined,
        "recoverableDays": 90
      }
    }
    

Integrazione con Configurazione app

Azure SDK fornisce un metodo helper, parseKeyVaultCertificateIdentifier, per analizzare l'ID certificato di Key Vault specificato. Ciò è necessario se si usano i riferimenti di Configurazione app a Key Vault. Configurazione app archivia l'ID certificato di Key Vault. È necessario il metodo parseKeyVaultCertificateIdentifier per analizzare tale ID per ottenere il nome del certificato. Dopo aver ottenuto il nome del certificato, è possibile ottenere il certificato corrente usando il codice di questa guida di avvio rapido.

Passaggi successivi

In questo argomento di avvio rapido è stato creato un insieme di credenziali delle chiavi e quindi è stato archiviato e recuperato un certificato. Per altre informazioni sul servizio Key Vault e su come integrarlo nelle applicazioni, continuare con questi articoli.