共用方式為


快速入門 - 適用於 JavaScript 的 Azure Key Vault 金鑰用戶端程式庫

開始使用適用於 JavaScript 的 Azure Key Vault 金鑰用戶端程式庫。 Azure Key Vault 是一項雲端服務,可為金鑰提供安全的存放區。 您也可以安全地儲存金鑰、密碼、憑證和其他祕密。 您可以透過 Azure 入口網站建立和管理 Azure 金鑰保存庫。 在本快速入門中,您會了解如何使用 JavaScript 金鑰用戶端程式庫,從 Azure Key Vault 建立、擷取和刪除金鑰。

Key Vault 用戶端程式庫資源:

API 參考文件 | 程式庫原始程式碼 | 套件 (npm)

如需有關 Key Vault 及金鑰的詳細資訊,請參閱:

必要條件

本快速入門假設您執行 Azure CLI

登入 Azure

  1. 執行 login 命令。

    az login
    

    如果此 CLI 可以開啟您的預設瀏覽器,它會開啟瀏覽器並載入 Azure 登入頁面。

    否則,請在 https://aka.ms/devicelogin 中開啟瀏覽器頁面,並輸入顯示在您的終端機中的授權碼。

  2. 請在瀏覽器中使用您的帳戶認證登入。

建立新的 Node.js 應用程式

建立一個使用金鑰保存庫的 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-keys

    npm install @azure/keyvault-keys
    
  2. 安裝 Azure 身分識別用戶端程式庫 @azure/identity 封裝,以向 Key Vault 進行驗證。

    npm install @azure/identity
    

授與對金鑰保存庫的存取權

若要透過角色型存取控制 (RBAC) 取得金鑰保存庫的權限,請使用 Azure CLI 命令 az role assignment create 將角色指派給「使用者主體名稱」(UPN)。

az role assignment create --role "Key Vault Crypto 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_URL 的環境變數。

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

驗證並建立用戶端

對大部分 Azure 服務的應用程式要求都必須獲得授權。 在程式碼中實作對 Azure 服務的無密碼連線時,建議使用 Azure.Identity 用戶端程式庫提供的 DefaultAzureCredential 方法。 DefaultAzureCredential 支援多個驗證方法,並在執行階段判斷應該使用哪個方法。 此方法可讓您的應用程式在不同的環境中 (本機或實際執行環境) 使用不同的驗證方法,而不需要實作環境特有的程式碼。

在本快速入門中,DefaultAzureCredential 使用已登入 Azure CLI 之本機開發使用者的認證向金鑰保存庫進行驗證。 將應用程式部署至 Azure 時,相同的 DefaultAzureCredential 程式碼可以自動探索並使用指派給 App Service、虛擬機器或其他服務的受控識別。 如需詳細資訊,請參閱受控識別概觀

在此程式碼中,金鑰保存庫的端點會用來建立金鑰保存庫用戶端。 端點格式看起來就像 https://<your-key-vault-name>.vault.azure.net,但主權雲端可能會變更。 如需對金鑰保存庫進行驗證的詳細資訊,請參閱開發人員指南

程式碼範例

以下的程式碼範例會示範如何建立用戶端、設定祕密、擷取祕密,以及刪除秘密。

此程式碼會使用下列 Key Vault 祕密類別和方法

設定應用程式架構

  • 建立新的文字檔,並將下列程式碼貼到 index.js 檔案中。

    const { KeyClient } = require("@azure/keyvault-keys");
    const { DefaultAzureCredential } = require("@azure/identity");
    
    async function main() {
    
        // 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 KeyClient(keyVaultUrl, credential);
    
        const uniqueString = Date.now();
        const keyName = `sample-key-${uniqueString}`;
        const ecKeyName = `sample-ec-key-${uniqueString}`;
        const rsaKeyName = `sample-rsa-key-${uniqueString}`;
    
        // Create key using the general method
        const result = await client.createKey(keyName, "EC");
        console.log("key: ", result);
    
        // Create key using specialized key creation methods
        const ecResult = await client.createEcKey(ecKeyName, { curve: "P-256" });
        const rsaResult = await client.createRsaKey(rsaKeyName, { keySize: 2048 });
        console.log("Elliptic curve key: ", ecResult);
        console.log("RSA Key: ", rsaResult);
    
        // Get a specific key
        const key = await client.getKey(keyName);
        console.log("key: ", key);
    
        // Or list the keys we have
        for await (const keyProperties of client.listPropertiesOfKeys()) {
        const key = await client.getKey(keyProperties.name);
        console.log("key: ", key);
        }
    
        // Update the key
        const updatedKey = await client.updateKeyProperties(keyName, result.properties.version, {
        enabled: false
        });
        console.log("updated key: ", updatedKey);
    
        // Delete the key - the key is soft-deleted but not yet purged
        const deletePoller = await client.beginDeleteKey(keyName);
        await deletePoller.pollUntilDone();
    
        const deletedKey = await client.getDeletedKey(keyName);
        console.log("deleted key: ", deletedKey);
    
        // Purge the key - the key is permanently deleted
        // This operation could take some time to complete
        console.time("purge a single key");
        await client.purgeDeletedKey(keyName);
        console.timeEnd("purge a single key");
    }
    
    main().catch((error) => {
      console.error("An error occurred:", error);
      process.exit(1);
    });
    

執行範例應用程式

  1. 執行應用程式:

    node index.js
    
  2. create 和 get 方法會傳回金鑰的完整 JSON 物件:

    "key":  {
      "key": {
        "kid": "https://YOUR-KEY-VAULT-ENDPOINT/keys/YOUR-KEY-NAME/YOUR-KEY-VERSION",
        "kty": "YOUR-KEY-TYPE",
        "keyOps": [ ARRAY-OF-VALID-OPERATIONS ],
        ... other properties based on key type
      },
      "id": "https://YOUR-KEY-VAULT-ENDPOINT/keys/YOUR-KEY-NAME/YOUR-KEY-VERSION",
      "name": "YOUR-KEY-NAME",
      "keyOperations": [ ARRAY-OF-VALID-OPERATIONS ],
      "keyType": "YOUR-KEY-TYPE",
      "properties": {
        "tags": undefined,
        "enabled": true,
        "notBefore": undefined,
        "expiresOn": undefined,
        "createdOn": 2021-11-29T18:29:11.000Z,
        "updatedOn": 2021-11-29T18:29:11.000Z,
        "recoverableDays": 90,
        "recoveryLevel": "Recoverable+Purgeable",
        "exportable": undefined,
        "releasePolicy": undefined,
        "vaultUrl": "https://YOUR-KEY-VAULT-ENDPOINT",
        "version": "YOUR-KEY-VERSION",
        "name": "YOUR-KEY-VAULT-NAME",
        "managed": undefined,
        "id": "https://YOUR-KEY-VAULT-ENDPOINT/keys/YOUR-KEY-NAME/YOUR-KEY-VERSION"
      }
    }
    
  • 建立新的文字檔,並將下列程式碼貼到 index.js 檔案中。

    import {
      KeyClient,
      KeyVaultKey,
      KeyProperties,
      DeletedKey,
    } from "@azure/keyvault-keys";
    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 printKey(keyVaultKey: KeyVaultKey): void {
      const { name, key, id, keyType, keyOperations, properties } = keyVaultKey;
      console.log("Key: ", { name, key, id, keyType });
    
      const { vaultUrl, version, enabled, expiresOn }: KeyProperties = properties;
      console.log("Key Properties: ", { vaultUrl, version, enabled, expiresOn });
    
      console.log("Key Operations: ", keyOperations.join(", "));
    }
    
    async function main(): Promise<void> {
      // Create a new KeyClient
      const client = new KeyClient(keyVaultUrl, credential);
    
      // Create unique key names
      const uniqueString = Date.now().toString();
      const keyName = `sample-key-${uniqueString}`;
      const ecKeyName = `sample-ec-key-${uniqueString}`;
      const rsaKeyName = `sample-rsa-key-${uniqueString}`;
    
      // Create a EC key
      const ecKey = await client.createKey(keyName, "EC");
      printKey(ecKey);
    
      // Elliptic curve key
      const ec256Key = await client.createEcKey(ecKeyName, {
        curve: "P-256",
      });
      printKey(ec256Key);
    
      // RSA key
      const rsa2048Key = await client.createRsaKey(rsaKeyName, {
        keySize: 2048,
      });
      printKey(rsa2048Key);
    
      // Get a key
      const key = await client.getKey(keyName);
      printKey(key);
    
      // Get properties of all keys
      for await (const keyProperties of client.listPropertiesOfKeys()) {
        const iteratedKey = await client.getKey(keyProperties.name);
        printKey(iteratedKey);
      }
    
      // Update key properties - disable key
      const updatedKey = await client.updateKeyProperties(
        keyName,
        ecKey.properties.version,
        {
          enabled: false,
        }
      );
      printKey(updatedKey);
    
      // Delete key (without immediate purge)
      const deletePoller = await client.beginDeleteKey(keyName);
      await deletePoller.pollUntilDone();
    
      // Get a deleted key
      const deletedKey = await client.getDeletedKey(keyName);
      console.log("deleted key: ", deletedKey.name);
    
      // Purge a deleted key
      console.time("purge a single key");
      await client.purgeDeletedKey(keyName);
      console.timeEnd("purge a single key");
    }
    
    main().catch((error) => {
      console.error("An error occurred:", error);
      process.exit(1);
    });
    

執行範例應用程式

  1. 組建 TypeScript 應用程式:

    tsc
    
  2. 執行應用程式:

    node index.js
    
  3. create 和 get 方法會傳回金鑰的完整 JSON 物件:

    "key":  {
      "key": {
        "kid": "https://YOUR-KEY-VAULT-ENDPOINT/keys/YOUR-KEY-NAME/YOUR-KEY-VERSION",
        "kty": "YOUR-KEY-TYPE",
        "keyOps": [ ARRAY-OF-VALID-OPERATIONS ],
        ... other properties based on key type
      },
      "id": "https://YOUR-KEY-VAULT-ENDPOINT/keys/YOUR-KEY-NAME/YOUR-KEY-VERSION",
      "name": "YOUR-KEY-NAME",
      "keyOperations": [ ARRAY-OF-VALID-OPERATIONS ],
      "keyType": "YOUR-KEY-TYPE",
      "properties": {
        "tags": undefined,
        "enabled": true,
        "notBefore": undefined,
        "expiresOn": undefined,
        "createdOn": 2021-11-29T18:29:11.000Z,
        "updatedOn": 2021-11-29T18:29:11.000Z,
        "recoverableDays": 90,
        "recoveryLevel": "Recoverable+Purgeable",
        "exportable": undefined,
        "releasePolicy": undefined,
        "vaultUrl": "https://YOUR-KEY-VAULT-ENDPOINT",
        "version": "YOUR-KEY-VERSION",
        "name": "YOUR-KEY-VAULT-NAME",
        "managed": undefined,
        "id": "https://YOUR-KEY-VAULT-ENDPOINT/keys/YOUR-KEY-NAME/YOUR-KEY-VERSION"
      }
    }
    

與應用程式組態整合

Azure SDK 提供協助程式方法 parseKeyVaultKeyIdentifier,以剖析指定 Key Vault 金鑰識別碼。 如果您使用對 Key Vault 的應用程式組態參考,則這是必要的。 App Config 會儲存 Key Vault 金鑰識別碼。 您需要 parseKeyVaultKeyIdentifier 方法來剖析該識別碼,以取得金鑰名稱。 有了金鑰名稱之後,您就可以使用此快速入門中的程式碼來取得目前的金鑰值。

下一步

在本快速入門中,您已建立金鑰保存庫、儲存金鑰,並擷取該金鑰。 若要深入了解 Key Vault,以及如何與應用程式整合的詳細資訊,請繼續閱讀以下文章。