Compartilhar via


Guia de Início Rápido – Biblioteca de clientes do certificado do Azure Key Vault para JavaScript

Introdução à biblioteca de clientes de certificados do Azure Key Vault para JavaScript. O Azure Key Vault é um serviço de nuvem que funciona como um repositório seguro de certificados. Você pode armazenar chaves, senhas, certificados e outros segredos com segurança. Os cofres de chaves do Azure podem ser criados e gerenciados por meio do portal do Azure. Neste guia de início rápido, você aprenderá a criar, recuperar e excluir certificados de um cofre de chaves do Azure usando a biblioteca de clientes JavaScript.

Recursos da biblioteca de clientes do Key Vault:

Documentação de referência da API | Código-fonte da biblioteca | Pacote (npm)

Para obter mais informações sobre o Key Vault e os certificados, confira:

Pré-requisitos

Este início rápido pressupõe que você esteja executando a CLI do Azure.

Entrar no Azure

  1. Execute o comando login.

    az login
    

    Se a CLI puder abrir o navegador padrão, ela o fará e carregará uma página de entrada do Azure.

    Caso contrário, abra uma página de navegador em https://aka.ms/devicelogin e insira o código de autorização exibido no terminal.

  2. Entre com suas credenciais de conta no navegador.

Criar um aplicativo Node.js

Crie um aplicativo Node.js que usa seu cofre de chaves.

  1. Em um terminal, crie uma pasta nomeada key-vault-node-app e altere para essa pasta:

    mkdir key-vault-node-app && cd key-vault-node-app
    
  2. Inicializar o projeto Node.js:

    npm init -y
    

Instalar pacotes do Key Vault

  1. Usando o terminal, instale a biblioteca de segredos do Azure Key Vault, @azure/keyvault-certificates para Node.js.

    npm install @azure/keyvault-certificates
    
  2. Instale a biblioteca de clientes da Identidade do Azure,@azure/identity, para autenticar em um Key Vault.

    npm install @azure/identity
    

Permitir acesso ao cofre de chaves

Para obter permissões para o cofre de chaves por meio do RBAC (controle de acesso baseado em função), atribua uma função ao seu UPN (nome principal do usuário) usando o comando da CLI do 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>"

Substitua <upn>, <subscription-id>, <resource-group-name> e <your-unique-keyvault-name> pelos valores reais. Seu UPN normalmente estará no formato de um endereço de email (por exemplo, username@domain.com).

Definir variáveis de ambiente

Este aplicativo está usando o ponto de extremidade do cofre de chaves como uma variável de ambiente chamada KEY_VAULT_URL.

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

Autenticar e criar um cliente

As solicitações do aplicativo para a maioria dos serviços do Azure precisam ser autorizadas. O uso do método DefaultAzureCredential fornecido pela biblioteca de clientes da Identidade do Azure é a abordagem recomendada para implementar conexões sem senha com os serviços do Azure no código. DefaultAzureCredential dá suporte a vários métodos de autenticação e determina quais métodos devem ser usados no runtime. Essa abordagem permite que seu aplicativo use diferentes métodos de autenticação em ambientes diferentes (local versus produção) sem implementar código específico do ambiente.

Neste guia de início rápido, DefaultAzureCredential se autenticará no cofre de chaves usando as credenciais do usuário de desenvolvimento local conectado à CLI do Azure. Quando o aplicativo é implantado no Azure, o mesmo código DefaultAzureCredential pode descobrir e usar automaticamente uma identidade gerenciada atribuída a um Serviço de Aplicativo, máquina virtual ou outros serviços. Para obter mais informações, confira Visão geral da Identidade Gerenciada.

Nesse código, o ponto de extremidade do cofre de chaves é usado para criar o cliente do cofre de chaves. O formato do ponto de extremidade é semelhante a https://<your-key-vault-name>.vault.azure.net, mas pode ser alterado para nuvens soberanas. Para obter mais informações sobre como se autenticar no cofre de chaves, confira Guia do Desenvolvedor.

Exemplo de código

Esse código usa os seguintes métodos e classes de certificado do Key Vault:

Configurar o framework de aplicativos

  • Crie um novo arquivo de texto e cole o código a seguir no arquivo 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);
    });
    

Executar o aplicativo de exemplo

  1. Executar o aplicativo:

    node index.js
    
  2. Os métodos create e get retornam um objeto JSON completo para o certificado:

    {
      "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
      }
    }
    
  • Crie um novo arquivo de texto e cole o código a seguir no arquivo 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);
    });
    

Executar o aplicativo de exemplo

  1. Criar o aplicativo TypeScript:

    tsc
    
  2. Executar o aplicativo:

    node index.js
    
  3. Os métodos create e get retornam um objeto JSON completo para o certificado:

    {
      "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
      }
    }
    

Integrando com a Configuração de Aplicativos do Azure

O SDK do Azure fornece um método auxiliar, parseKeyVaultCertificateIdentifier, para analisar a ID do certificado do Key Vault fornecida, que será necessário se você usar as referências de Configuração de Aplicativos para o Key Vault. A Configuração de Aplicativos armazena uma ID do certificado do Key Vault. Você precisa do método parseKeyVaultCertificateIdentifier para analisar essa ID e obter o nome do certificado. Depois de obter o nome do certificado, você poderá obter o certificado atual usando o código deste guia de início rápido.

Próximas etapas

Neste guia de início rápido, você criou um cofre de chaves e armazenou e recuperou um certificado. Para saber mais sobre o Key Vault e como integrá-lo aos aplicativos, continue lendo estes artigos.