Partilhar via


Criar um token SAS de delegação de usuário com o Armazenamento de Blobs do Azure e JavaScript

Este artigo mostra como criar um token SAS de delegação de usuário na biblioteca de cliente do Armazenamento de Blobs do Azure v12 para JavaScript. Uma SAS de delegação de usuário, introduzida com a versão 2018-11-09, é protegida com credenciais do Microsoft Entra e é suportada pelo serviço Blob apenas para:

  • Conceda acesso a um contêiner existente.
  • Conceda acesso para criar, usar e excluir blobs.

Para criar uma SAS de delegação de usuário, um cliente deve ter permissões para chamar a operação blobServiceClient.getUserDelegationKey . A chave retornada por esta operação é usada para assinar a SAS de delegação de usuário. A entidade de segurança que chama essa operação deve receber uma função RBAC que inclua Microsoft.Storage/storageAccounts/blobServices/generateUserDelegationKey/action.

As permissões concedidas a um cliente que possui a SAS são a interseção das permissões concedidas à entidade de segurança que solicitou a chave de delegação do usuário e as permissões concedidas ao recurso no token SAS no campo de permissões assinadas (sp). Se uma permissão concedida à entidade de segurança via RBAC também não for concedida no token SAS, essa permissão não será concedida ao cliente que tentar usar a SAS para acessar o recurso.

Os trechos de código de exemplo estão disponíveis no GitHub como arquivos Node.js executáveis.

Pacote (npm) | Exemplos | Referência da API Código-fonte | | da biblioteca Enviar comentários

Práticas recomendadas para tokens SAS de delegação de usuários

Como qualquer pessoa com o token SAS pode usá-lo para acessar o contêiner e os blobs, você deve definir o token SAS com as permissões mais restritivas que ainda permitem que o token conclua as tarefas necessárias.

Práticas recomendadas para tokens SAS

Usar o DefaultAzureCredential na Nuvem do Azure

Para autenticar no Azure, sem segredos, configure a identidade gerenciada. Essa abordagem permite que seu código use DefaultAzureCredential.

Para configurar a identidade gerenciada para a nuvem do Azure:

  • Criar uma identidade gerenciada
  • Definir as funções de armazenamento apropriadas para a identidade
  • Configure seu ambiente do Azure para trabalhar com sua identidade gerenciada

Quando essas duas tarefas estiverem concluídas, use o DefaultAzureCredential em vez de uma cadeia de conexão ou chave de conta. Essa abordagem permite que todos os seus ambientes usem exatamente o mesmo código-fonte sem a questão de usar segredos no código-fonte.

Usar o DefaultAzureCredential no desenvolvimento local

Em seu ambiente de desenvolvimento local, sua identidade do Azure (sua conta pessoal ou de desenvolvimento que você usa para entrar no portal do Azure) precisa se autenticar no Azure para usar o mesmo código em tempos de execução locais e na nuvem.

Contêiner: adicione as dependências necessárias ao seu aplicativo

Inclua as dependências necessárias para criar um token SAS de contêiner.

const {
    DefaultAzureCredential
} = require('@azure/identity');
const {
    ContainerClient,
    BlobServiceClient,
    ContainerSASPermissions,
    generateBlobSASQueryParameters,
    SASProtocol
} = require('@azure/storage-blob');

// used for local environment variables
require('dotenv').config();

Container: obter variáveis de ambiente

O nome da conta de Armazenamento de Blobs e o nome do contêiner são os valores mínimos necessários para criar um token SAS de contêiner:

// Get environment variables for DefaultAzureCredential
const accountName = process.env.AZURE_STORAGE_ACCOUNT_NAME;
const containerName = process.env.AZURE_STORAGE_BLOB_CONTAINER_NAME;

Criar uma SAS com DefaultAzureCredential

As seguintes etapas conceituais são necessárias para criar um token SAS com DefaultAzureCredential:

  • Configurar DefaultAzureCredential
    • Desenvolvimento local - use identidade pessoal e defina funções para armazenamento
    • Azure cloud - criar identidade gerenciada
  • Use DefaultAzureCredential para obter a chave de delegação do usuário com UserDelegationKey
  • Use a chave de delegação do usuário para construir o token SAS com os campos apropriados com generateBlobSASQueryParameters

Contêiner: crie token SAS com DefaultAzureCredential

Com a identidade configurada, use o seguinte código para criar o token SAS de delegação de usuário para uma conta e contêiner existentes:

// 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;
}

O código do servidor anterior cria um fluxo de valores para criar o token SAS do contêiner:

Depois de criar o token SAS do contêiner, você pode fornecê-lo ao cliente que consumirá o token. O cliente pode usá-lo para listar os blobs em um contêiner. Um exemplo de código de cliente mostra como testar o SAS como um consumidor.

Contêiner: use o token SAS

Depois que o token SAS do contêiner for criado, use o token. Como exemplo de uso do token SAS, você:

  • Construa uma URL completa, incluindo o nome do contêiner e a cadeia de caracteres de consulta. A cadeia de caracteres de consulta é o token SAS.
  • Crie um ContainerClient com a URL do contêiner.
  • Use o cliente: neste exemplo, liste blobs no contêiner com listBlobsFlat.
// 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: adicione as dependências necessárias ao seu aplicativo

Inclua as dependências necessárias para criar o token SAS n blob.

const {
    DefaultAzureCredential
} = require('@azure/identity');
const {
    BlockBlobClient,
    BlobServiceClient,
    BlobSASPermissions,
    generateBlobSASQueryParameters,
    SASProtocol
} = require('@azure/storage-blob');

// used for local environment variables
require('dotenv').config();

Blob: obter variáveis de ambiente

O nome da conta de Armazenamento de Blob e o nome do contêiner são os valores mínimos necessários para criar um token SAS de blob:

const accountName = process.env.AZURE_STORAGE_ACCOUNT_NAME;
const containerName = process.env.AZURE_STORAGE_BLOB_CONTAINER_NAME;

Quando você precisa criar um token SAS blob, você precisa ter o nome do blob para criar o token SAS. Isso será predeterminado, como um nome de blob aleatório, um nome de blob enviado pelo usuário ou um nome gerado a partir do seu aplicativo.

// Create random blob name for text file
const blobName = `${(0|Math.random()*9e6).toString(36)}.txt`;

Blob: crie token SAS com DefaultAzureCredential

Com a identidade configurada, use o seguinte código para criar o token SAS de delegação de usuário para uma conta e contêiner existentes:

// 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;
}

O código anterior cria um fluxo de valores para criar o token SAS do contêiner:

Depois de criar o token SAS blob, você pode fornecê-lo ao cliente que consumirá o token. O cliente pode usá-lo para carregar um blob. Um exemplo de código de cliente mostra como testar o SAS como um consumidor.

Blob: use o token SAS

Depois que o token SAS de blob for criado, use o token. Como exemplo de uso do token SAS, você:

  • Construa uma URL completa, incluindo nome do contêiner, nome do blob e cadeia de caracteres de consulta. A cadeia de caracteres de consulta é o token SAS.
  • Crie um BlockBlobClient com a URL do contêiner.
  • Use o cliente: neste exemplo, carregue o blob com upload.
// 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);    
}

Consulte também