Compartilhar via

快速入门:适用于 JavaScript 的Azure Key Vault证书客户端库

开始使用适用于 JavaScript 的 Azure Key Vault 证书客户端库。 Azure Key Vault是一种云服务,可为证书提供安全存储。 可以安全地存储密钥、密码、证书和其他机密。 可以通过Azure portal创建和管理Azure密钥保管库。 本快速入门介绍如何使用 JavaScript 客户端库从Azure key vault创建、检索和删除证书。

Key Vault客户端库资源:

API 参考文档 | Library 源代码 | Package (npm)

有关Key Vault和证书的详细信息,请参阅:

先决条件

本快速入门假定你正在运行 Azure CLI

登录到 Azure

  1. 运行 login 命令。

    az login
    

    如果 CLI 可以打开默认浏览器,它将执行此作并加载Azure登录页。

    否则,请在 https://aka.ms/deviceloginchina 处打开浏览器页,然后输入终端中显示的授权代码。

  2. 在浏览器中使用帐户凭据登录。

创建新的 Node.js 应用程序

创建使用key vault的 Node.js 应用程序。

  1. 在终端中,创建一个名为 key-vault-node-app 的文件夹并更改为该文件夹:

    mkdir key-vault-node-app && cd key-vault-node-app
    
  2. 初始化 Node.js 项目:

    npm init -y
    

安装 Key Vault 软件包

  1. 使用终端安装用于Node.js的Azure Key Vault密钥库@azure/keyvault-certificates

    npm install @azure/keyvault-certificates
    
  2. 安装Azure标识客户端库(@azure/identity)对Key Vault进行身份验证。

    npm install @azure/identity
    

向您的密钥库授予访问权限

若要通过 Role-Based Access Control (RBAC)获取key vault的权限,请使用 Azure CLI 命令 az role assignment create 将角色分配给“用户主体名称”(UPN)。

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

将 <upn>、<subscription-id>、<resource-group-name> 和 <your-unique-keyvault-name> 替换为你的实际值。 你的 UPN 通常采用电子邮件地址格式(例如 username@domain.com)。

设置环境变量

此应用程序使用 key vault 终结点作为名为 KEY_VAULT_URL 的环境变量。

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

进行身份验证并创建客户端

对大多数Azure服务的应用程序请求必须获得授权。 建议使用由 Azure 标识客户端库DefaultAzureCredential> 方法实现与代码中Azure服务的无密码连接。 DefaultAzureCredential 支持多种身份验证方法,并确定应在运行时使用哪种方法。 通过这种方法,你的应用可在不同环境(本地与生产)中使用不同的身份验证方法,而无需实现特定于环境的代码。

在本快速入门中,DefaultAzureCredential 使用已通过 Azure CLI 登录的本地开发用户的凭据对密钥保管库进行身份验证。 将应用程序部署到Azure时,同一DefaultAzureCredential代码可以自动发现和使用分配给App Service、虚拟机或其他服务的托管标识。 有关详细信息,请参阅 Managed Identity Overview

在此代码中,密钥保管库的终结点用于创建密钥保管库客户端。 终结点格式类似于 https://<your-key-vault-name>.vault.azure.cn,但对于专用云可能会更改。 有关向 key vault 进行身份验证的详细信息,请参阅 Developer 指南

代码示例

此代码使用以下 Key Vault 证书类和方法

设置应用框架

  • 创建新文本文件并将以下代码粘贴到 index.js 文件中。

    const { CertificateClient, DefaultCertificatePolicy } = require("@azure/keyvault-certificates");
    const { DefaultAzureCredential } = require("@azure/identity");
    
    async function main() {
      // DefaultAzureCredential automatically uses managed identity in Azure environments.
      // For local development, it uses credentials from Azure CLI, Azure PowerShell, or environment variables.
      // See: https://learn.microsoft.com/javascript/api/@azure/identity/defaultazurecredential
      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);
    });
    

运行示例应用程序

  1. 运行应用:

    node index.js
    
  2. create 和 get 方法为证书返回完整的 JSON 对象:

    {
      "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.vault.azure.cn/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.vault.azure.cn",
        "version": "YOUR-CERTIFICATE-VERSION",
        "tags": undefined,
        "x509Thumbprint": undefined,
        "recoverableDays": 90
      }
    }
    
  • 创建新的文本文件,并将以下代码粘贴到 index.ts 文件中
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);
});

运行示例应用程序

  1. 构建 TypeScript 应用:

    tsc
    
  2. 运行应用:

    node index.js
    
  3. create 和 get 方法为证书返回完整的 JSON 对象:

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

与 App Configuration 集成

Azure SDK 提供了一个帮助方法 parseKeyVaultCertificateIdentifier,用于解析指定的 Key Vault 证书 ID,该步骤在使用 App Configuration 引用 Key Vault 时是必要的。 应用配置存储了 Key Vault 证书的 ID。 需要 parseKeyVaultCertificateIdentifier 方法来分析该 ID 以获取证书名称。 获取证书名称后,可以使用本快速入门中的代码获取当前证书。

后续步骤

在本快速入门中,你创建了一个key vault,存储了一个证书,并检索了该证书。 若要详细了解Key Vault以及如何将其与应用程序集成,请继续阅读以下文章。