使用 Azure Blob 儲存體和 JavaScript 建立使用者委派 SAS 權杖
本文說明如何在 JavaScript 的 Azure Blob 儲存體用戶端程式庫 v12 中,建立使用者委派 SAS 權杖。 2018-11-09 版引進的使用者委派 SAS 會經過 Microsoft Entra 認證保護,且僅支援 Blob 服務:
- 授與現有容器存取權。
- 授與建立、使用和刪除 Blob 的存取權。
若要建立使用者委派 SAS,用戶端必須具有呼叫 blobServiceClient.getUserDelegationKey 作業的許可權。 此作業傳回的金鑰可用來簽署使用者委派 SAS。 呼叫此作業的安全性主體必須被指派包含 Microsoft.Storage/storageAccounts/blobServices/generateUserDelegationKey/action 的 RBAC 角色。
授與具有 SAS 用戶端的權限包含了授與安全性主體 (要求使用者委派金鑰) 的權限,以及在簽署的權限 (sp) 欄位中,授與 SAS 權杖資源的權限。 如果透過 RBAC 授與安全性主體的權限並未在 SAS 權杖上授與,則不會將該權限授與嘗試使用 SAS 存取資源的用戶端。
範例程式碼片段可在 GitHub 中以可執行的 Node.js 檔案形式來取得。
套件 (npm) | 範例 | API 參考 | 程式庫原始程式碼 | 提供意見反應
使用者委派 SAS 權杖的最佳做法
由於具有 SAS 權杖的任何人都可以用其來存取容器和 Blob,因此您應該使用最嚴格的權限來定義 SAS 權杖 (該權限仍允許權杖完成所需的工作)。
在 Azure Cloud 中使用 DefaultAzureCredential
若要在不使用密碼的情況下向 Azure 驗證,請設定受控識別。 此方法可讓您的程序代碼使用 DefaultAzureCredential。
若要設定 Azure 雲端的受控識別:
- 建立受控識別
- 為身分識別設定適當的儲存體角色
- 設定您的 Azure 環境以搭配受控識別
當這兩個工作完成時,請使用 DefaultAzureCredential,而不是連接字串或帳戶金鑰。 這種方法可讓您的所有環境使用完全相同的 原始程式碼 ,而不需要在原始程式碼中使用秘密。
在本機開發過程中使用 DefaultAzureCredential
在本機開發環境中,您的 Azure 身分識別 (您用來登入 Azure 入口網站的個人或開發帳戶) 需要向 Azure 驗證,才能在本機和雲端執行階段中使用相同程式碼。
容器:將必要的相依性新增至您的應用程式
包含建立容器 SAS 權杖所需的相依性。
const {
DefaultAzureCredential
} = require('@azure/identity');
const {
ContainerClient,
BlobServiceClient,
ContainerSASPermissions,
generateBlobSASQueryParameters,
SASProtocol
} = require('@azure/storage-blob');
// used for local environment variables
require('dotenv').config();
容器:取得環境變數
Blob 儲存體帳戶名稱和容器名稱是建立容器 SAS 權杖所需的最小值:
// Get environment variables for DefaultAzureCredential
const accountName = process.env.AZURE_STORAGE_ACCOUNT_NAME;
const containerName = process.env.AZURE_STORAGE_BLOB_CONTAINER_NAME;
使用 DefaultAzureCredential 建立 SAS
使用 DefaultAzureCredential 建立 SAS 權杖需要下列概念步驟:
- 設定 DefaultAzureCredential
- 本機開發 - 使用個人身分識別並設定儲存體的角色
- Azure 雲端 - 建立受控識別
- 使用 DefaultAzureCredential 透過 UserDelegationKey 取得使用者委派金鑰
- 使用使用者委派金鑰搭配 generateBlobSASQueryParameters 的適當欄位來建構 SAS 權杖
容器:使用 DefaultAzureCredential 建立 SAS 權杖
設定身分識別後,請使用下列程式碼為現有帳戶和容器建立使用者委派 SAS 權杖:
// Server creates User Delegation SAS Token for container
async function createContainerSas() {
// Get environment variables
const accountName = process.env.AZURE_STORAGE_ACCOUNT_NAME;
const containerName = process.env.AZURE_STORAGE_BLOB_CONTAINER_NAME;
// Best practice: create time limits
const TEN_MINUTES = 10 * 60 * 1000;
const NOW = new Date();
// Best practice: set start time a little before current time to
// make sure any clock issues are avoided
const TEN_MINUTES_BEFORE_NOW = new Date(NOW.valueOf() - TEN_MINUTES);
const TEN_MINUTES_AFTER_NOW = new Date(NOW.valueOf() + TEN_MINUTES);
// Best practice: use managed identity - DefaultAzureCredential
const blobServiceClient = new BlobServiceClient(
`https://${accountName}.blob.core.windows.net`,
new DefaultAzureCredential()
);
// Best practice: delegation key is time-limited
// When using a user delegation key, container must already exist
const userDelegationKey = await blobServiceClient.getUserDelegationKey(
TEN_MINUTES_BEFORE_NOW,
TEN_MINUTES_AFTER_NOW
);
// Need only list permission to list blobs
const containerPermissionsForAnonymousUser = "l";
// Best practice: SAS options are time-limited
const sasOptions = {
containerName,
permissions: ContainerSASPermissions.parse(containerPermissionsForAnonymousUser),
protocol: SASProtocol.HttpsAndHttp,
startsOn: TEN_MINUTES_BEFORE_NOW,
expiresOn: TEN_MINUTES_AFTER_NOW
};
const sasToken = generateBlobSASQueryParameters(
sasOptions,
userDelegationKey,
accountName
).toString();
return sasToken;
}
上述伺服器程式碼會建立值的流程,以建立容器 SAS 權杖:
- 使用 DefaultAzureCredential 建立 BlobServiceClient
- 使用 blobServiceClient.getUserDelegationKey 作業建立 UserDelegationKey
- 使用金鑰建立具有 generateBlobSASQueryParameters 的 SAS 權杖字串
建立容器 SAS 權杖之後,您可以將其提供給將取用權杖的用戶端。 用戶端接著可以用來列出容器中的 Blob。 用戶端程式代碼範例會顯示如何將 SAS 測試為取用者。
容器:使用 SAS 權杖
建立容器 SAS 權杖之後,請使用權杖。 作為使用 SAS 權杖的範例,您可以:
- 建構完整的 URL,包括容器名稱和查詢字串。 查詢字串是 SAS 權杖。
- 使用容器 URL 建立 ContainerClient。
- 使用用戶端:在此範例中,使用 listBlobsFlat 列出容器中的 Blob。
// Client or another process uses SAS token to use container
async function listBlobs(sasToken){
// Get environment variables
const accountName = process.env.AZURE_STORAGE_ACCOUNT_NAME;
const containerName = process.env.AZURE_STORAGE_BLOB_CONTAINER_NAME;
// Create Url
// SAS token is the query string with typical `?` delimiter
const sasUrl = `https://${accountName}.blob.core.windows.net/${containerName}?${sasToken}`;
console.log(`\nContainerUrl = ${sasUrl}\n`);
// Create container client from SAS token url
const containerClient = new ContainerClient(sasUrl);
let i = 1;
// List blobs in container
for await (const blob of containerClient.listBlobsFlat()) {
console.log(`Blob ${i++}: ${blob.name}`);
}
}
容器:將必要的相依性新增至您的應用程式
包含建立 Blob SAS 權杖所需的相依性。
const {
DefaultAzureCredential
} = require('@azure/identity');
const {
BlockBlobClient,
BlobServiceClient,
BlobSASPermissions,
generateBlobSASQueryParameters,
SASProtocol
} = require('@azure/storage-blob');
// used for local environment variables
require('dotenv').config();
Blob:設定環境變數
Blob 儲存體帳戶名稱和容器名稱是建立 Blob SAS 權杖所需的最小值:
const accountName = process.env.AZURE_STORAGE_ACCOUNT_NAME;
const containerName = process.env.AZURE_STORAGE_BLOB_CONTAINER_NAME;
當您需要建立 Blob SAS 權杖時,必須有 Blob 名稱才能建立 SAS 權杖。 這會預先決定,例如隨機 Blob 名稱、使用者提交的 Blob 名稱,或從您的應用程式產生的名稱。
// Create random blob name for text file
const blobName = `${(0|Math.random()*9e6).toString(36)}.txt`;
容器:使用 DefaultAzureCredential 建立 SAS 權杖
設定身分識別後,請使用下列程式碼為現有帳戶和容器建立使用者委派 SAS 權杖:
// Server creates User Delegation SAS Token for blob
async function createBlobSas(blobName) {
// Get environment variables
const accountName = process.env.AZURE_STORAGE_ACCOUNT_NAME;
const containerName = process.env.AZURE_STORAGE_BLOB_CONTAINER_NAME;
// Best practice: create time limits
const TEN_MINUTES = 10 * 60 * 1000;
const NOW = new Date();
// Best practice: set start time a little before current time to
// make sure any clock issues are avoided
const TEN_MINUTES_BEFORE_NOW = new Date(NOW.valueOf() - TEN_MINUTES);
const TEN_MINUTES_AFTER_NOW = new Date(NOW.valueOf() + TEN_MINUTES);
// Best practice: use managed identity - DefaultAzureCredential
const blobServiceClient = new BlobServiceClient(
`https://${accountName}.blob.core.windows.net`,
new DefaultAzureCredential()
);
// Best practice: delegation key is time-limited
// When using a user delegation key, container must already exist
const userDelegationKey = await blobServiceClient.getUserDelegationKey(
TEN_MINUTES_BEFORE_NOW,
TEN_MINUTES_AFTER_NOW
);
// Need only create/write permission to upload file
const blobPermissionsForAnonymousUser = "cw"
// Best practice: SAS options are time-limited
const sasOptions = {
blobName,
containerName,
permissions: BlobSASPermissions.parse(blobPermissionsForAnonymousUser),
protocol: SASProtocol.HttpsAndHttp,
startsOn: TEN_MINUTES_BEFORE_NOW,
expiresOn: TEN_MINUTES_AFTER_NOW
};
const sasToken = generateBlobSASQueryParameters(
sasOptions,
userDelegationKey,
accountName
).toString();
return sasToken;
}
上述程式碼會建立值的流程,以建立容器 SAS 權杖:
- 使用 DefaultAzureCredential 建立 BlobServiceClient
- 使用 blobServiceClient.getUserDelegationKey 作業建立 UserDelegationKey
- 使用金鑰來建立 SAS 權杖字串。 如果未在選項中指定 Blob 名稱,SAS 權杖就是容器權杖。
建立容器 SAS 權杖之後,您可以將其提供給將取用權杖的用戶端。 用戶端接著可以將其用來上傳 Blob。 用戶端程式代碼範例會顯示如何將 SAS 測試為取用者。
Blob:使用 SAS 權杖
建立 Blob SAS 權杖之後,請使用權杖。 作為使用 SAS 權杖的範例,您可以:
- 建構完整的 URL,包括容器名稱、Blob 名稱和查詢字串。 查詢字串是 SAS 權杖。
- 使用容器 URL 建立 BlockBlobClient。
- 使用用戶端:在此範例中,透過上傳來上傳 Bob。
// Client or another process uses SAS token to upload content to blob
async function uploadStringToBlob(blobName, sasToken, textAsString){
// Get environment variables
const accountName = process.env.AZURE_STORAGE_ACCOUNT_NAME;
const containerName = process.env.AZURE_STORAGE_BLOB_CONTAINER_NAME;
// Create Url SAS token as query string with typical `?` delimiter
const sasUrl = `https://${accountName}.blob.core.windows.net/${containerName}/${blobName}?${sasToken}`;
console.log(`\nBlobUrl = ${sasUrl}\n`);
// Create blob client from SAS token url
const blockBlobClient = new BlockBlobClient(sasUrl);
// Upload string
await blockBlobClient.upload(textAsString, textAsString.length, undefined);
}