Criar uma SAS de serviço para um blob com .NET

Uma SAS (Assinatura de Acesso Compartilhado) permite conceder acesso limitado a contêineres e blobs da conta de armazenamento. Ao criar uma SAS, você especificará suas restrições, inclusive que recursos do Armazenamento do Azure um cliente terá permissão para acessar, que permissões ele terá nesses recursos e por quanto tempo a SAS é válida.

Cada SAS é assinada com uma chave. Você pode assinar uma SAS de uma das duas maneiras:

  • Com uma chave criada utilizando as credenciais do Microsoft Entra. Uma SAS assinada com credenciais do Microsoft Entra é uma SAS de delegação de usuário. É necessário atribuir um cliente que cria uma SAS de delegação de usuário a uma função RBAC do Azure que inclua a ação Microsoft.Storage/storageAccounts/blobServices/generateUserDelegationKey. Para saber mais, consulte Criar uma SAS de delegação de usuário.
  • Com uma chave da conta de armazenamento. Tanto uma SAS de serviço quanto uma SAS de conta são assinadas com a chave da conta de armazenamento. É necessário que o cliente que cria uma SAS de serviço tenha acesso direto à chave da conta ou receba a permissão Microsoft.Storage/storageAccounts/listkeys/action. Para saber mais, consulte Criar uma SAS de serviço ou Criar uma SAS de conta.

Observação

Uma SAS de delegação de usuário oferece mais segurança do que uma SAS que é assinada com a chave da conta de armazenamento. A Microsoft recomenda usar uma SAS de delegação de usuário quando possível. Para saber mais, confira Conceder acesso limitado a dados com assinaturas de acesso compartilhado (SAS).

Este artigo mostra como usar a chave de conta de armazenamento para criar uma SAS de serviço para um blob com a biblioteca de clientes do Armazenamento de Blobs do Azure para .NET.

Sobre a SAS de serviço

Uma SAS de serviço é assinada com a chave de acesso da conta. Você pode usar a classe StorageSharedKeyCredential para criar a credencial usada para assinar a SAS de serviço.

Você também pode usar uma política de acesso armazenada para definir as permissões e a duração da SAS. Se o nome de uma política de acesso armazenada existente for fornecido, essa política está associada com a SAS. Para saber mais sobre as políticas de acesso armazenadas, veja Definir uma política de acesso armazenada. Se nenhuma política de acesso armazenada for fornecida, os exemplos de código neste artigo mostrarão como definir permissões e duração para a SAS.

Criar um serviço SAS para um blob

O código a seguir mostra como criar um SAS de serviço para um recurso de blob. Primeiro, o código verifica se o objeto BlobClient está autorizado com uma credencial de chave compartilhada verificando a propriedade CanGenerateSasUri. Em seguida, ele gera a SAS de serviço por meio da classe BlobSasBuilder e chama GenerateSasUri para criar um URI SAS de serviço com base nos objetos do cliente e do construtor.

public static async Task<Uri> CreateServiceSASBlob(
    BlobClient blobClient,
    string storedPolicyName = null)
{
    // Check if BlobContainerClient object has been authorized with Shared Key
    if (blobClient.CanGenerateSasUri)
    {
        // Create a SAS token that's valid for one day
        BlobSasBuilder sasBuilder = new BlobSasBuilder()
        {
            BlobContainerName = blobClient.GetParentBlobContainerClient().Name,
            BlobName = blobClient.Name,
            Resource = "b"
        };

        if (storedPolicyName == null)
        {
            sasBuilder.ExpiresOn = DateTimeOffset.UtcNow.AddDays(1);
            sasBuilder.SetPermissions(BlobContainerSasPermissions.Read);
        }
        else
        {
            sasBuilder.Identifier = storedPolicyName;
        }

        Uri sasURI = blobClient.GenerateSasUri(sasBuilder);

        return sasURI;
    }
    else
    {
        // Client object is not authorized via Shared Key
        return null;
    }
}

Usar uma SAS de serviço para autorizar um objeto cliente

O exemplo de código a seguir mostra como usar a SAS de serviço para autorizar um objeto BlobClient. Esse objeto de cliente pode ser usado para executar operações no recurso de blob com base nas permissões concedidas pela SAS.

Primeiro, crie um objeto BlobServiceClient assinado com a chave de acesso da conta:

string accountName = "<storage-account-name>";
string accountKey = "<storage-account-key";
StorageSharedKeyCredential storageSharedKeyCredential =
    new(accountName, accountKey);
BlobServiceClient blobServiceClient = new BlobServiceClient(
    new Uri($"https://{accountName}.blob.core.windows.net"),
    storageSharedKeyCredential);

Em seguida, gere a SAS de serviço conforme mostrado no exemplo anterior e use a SAS para autorizar um objeto BlobClient:

// Create a Uri object with a service SAS appended
BlobClient blobClient = blobServiceClient
    .GetBlobContainerClient("sample-container")
    .GetBlobClient("sample-blob.txt");
Uri blobSASURI = await CreateServiceSASBlob(blobClient);

// Create a blob client object representing 'sample-blob.txt' with SAS authorization
BlobClient blobClientSAS = new BlobClient(blobSASURI);

Definir uma política de acesso armazenada

Uma política de acesso armazenada fornece um nível de controle adicional sobre uma assinatura de acesso compartilhado (SAS) no nível de serviço no lado do servidor. Estabelecer uma política de acesso armazenada serve para agrupar assinaturas de acesso compartilhado e fornecer restrições adicionais para assinaturas que são associadas pela política.

Você pode usar uma política de acesso armazenada para alterar a hora de início, a hora de expiração ou as permissões de uma assinatura. Você também pode usar uma política de acesso armazenada para revogar uma assinatura após a sua emissão. Esta seção se concentra em contêineres de blob, mas também há suporte para políticas de acesso armazenada para compartilhamentos de arquivos, filas e tabelas.

Para gerenciar políticas de acesso armazenadas em um recurso de contêiner, chame um dos seguintes métodos de um objeto BlobContainerClient:

Criar ou modificar uma política de acesso armazenada

Você pode definir no máximo cinco políticas de acesso em um recurso de cada vez. Cada campo SignedIdentifier, com seu campo Id exclusivo, corresponde a uma política de acesso. Tentar definir mais de cinco políticas de acesso ao mesmo tempo faz com que o serviço retorne o código de status 400 (Bad Request).

O exemplo de código a seguir mostra como criar duas políticas de acesso armazenadas em um recurso de contêiner:

public static async Task CreateStoredAccessPolicyAsync(BlobContainerClient containerClient)
{
    // Create a stored access policy with read and write permissions, valid for one day
    List<BlobSignedIdentifier> signedIdentifiers = new List<BlobSignedIdentifier>
    {
        new BlobSignedIdentifier
        {
            Id = "sample-read-write-policy",
            AccessPolicy = new BlobAccessPolicy
            {
                StartsOn = DateTimeOffset.UtcNow,
                ExpiresOn = DateTimeOffset.UtcNow.AddDays(1),
                Permissions = "rw"
            }
        },
        new BlobSignedIdentifier
        {
            Id = "sample-read-policy",
            AccessPolicy = new BlobAccessPolicy
            {
                StartsOn = DateTimeOffset.UtcNow,
                ExpiresOn = DateTimeOffset.UtcNow.AddDays(1),
                Permissions = "r"
            }
        }
    };

    // Set the container's access policy
    await containerClient.SetAccessPolicyAsync(permissions: signedIdentifiers);
}

Você também pode modificar uma política existente. O exemplo de código a seguir mostra como modificar uma única política de acesso armazenada para atualizar a data de validade da política:

public static async Task ModifyStoredAccessPolicyAsync(BlobContainerClient containerClient)
{
    BlobContainerAccessPolicy accessPolicy = await containerClient.GetAccessPolicyAsync();
    List<BlobSignedIdentifier> signedIdentifiers = accessPolicy.SignedIdentifiers.ToList();

    // Modify the expiration date a single policy
    var samplePolicy = signedIdentifiers.FirstOrDefault(item => item.Id == "sample-read-policy");
    samplePolicy.AccessPolicy.PolicyExpiresOn = DateTimeOffset.UtcNow.AddDays(7);

    // Update the container's access policy
    await containerClient.SetAccessPolicyAsync(permissions: signedIdentifiers);
}

Revogar ou excluir uma política de acesso armazenada

Para revogar uma política de acesso armazenada, você pode excluí-la, renomeá-la alterando o identificador assinado ou alterar a hora de expiração para um valor no passado. A alteração do identificador assinado interrompe as associações entre todas as assinaturas existentes e a política de acesso armazenada. A alteração da hora de expiração para um valor no passado faz com que todas as assinaturas associadas expirem. A exclusão ou modificação da política de acesso armazenada afeta imediatamente todas as assinaturas de acesso compartilhadas associadas a ela.

O exemplo de código a seguir mostra como revogar uma política alterando a propriedade Id do identificador assinado:

public static async Task RevokeStoredAccessPolicyAsync(BlobContainerClient containerClient)
{
    BlobContainerAccessPolicy accessPolicy = await containerClient.GetAccessPolicyAsync();
    List<BlobSignedIdentifier> signedIdentifiers = accessPolicy.SignedIdentifiers.ToList();

    // Revoke a single policy by changing its name
    var samplePolicy = signedIdentifiers.FirstOrDefault(item => item.Id == "sample-read-policy");
    samplePolicy.Id = "sample-read-policy-revoke";

    // Update the container's access policy
    await containerClient.SetAccessPolicyAsync(permissions: signedIdentifiers);
}

Você também pode remover todas as políticas de acesso de um recurso de contêiner chamando SetAccessPolicyAsync com um parâmetro permissions vazio. O exemplo a seguir mostra como excluir todas as políticas de acesso armazenadas de um contêiner especificado:

public static async Task DeleteStoredAccessPolicyAsync(BlobContainerClient containerClient)
{
    // Remove all stored access policies for the container resource
    await containerClient.SetAccessPolicyAsync();
}

Recursos

Para saber mais sobre como criar um SAS de serviço usando a biblioteca de clientes do Armazenamento de Blobs do Azure para o .NET, consulte os recursos a seguir.

Recursos da biblioteca de clientes

Confira também