Creare una firma di accesso condiviso di delega utente per un contenitore, una directory o un BLOB con .NET

Una firma di accesso condiviso consente di concedere l'accesso limitato a contenitori e BLOB nell'account di archiviazione. Quando si crea una firma di accesso condiviso, si specificano i relativi vincoli, incluse le risorse di archiviazione di Azure a cui un client può accedere, le autorizzazioni per tali risorse e il tempo di validità della firma di accesso condiviso.

Ogni firma di accesso condiviso è firmata con una chiave. È possibile firmare una firma di accesso condiviso in uno dei due modi seguenti:

  • Con una chiave creata con le credenziali Azure Active Directory (Azure AD). Una firma di accesso condiviso con Azure AD credenziali è una firma di accesso condiviso dell'utente .
  • Con la chiave dell'account di archiviazione. Una firma di accesso condiviso del servizio e una firma di accesso condiviso dell' account sono firmate con la chiave account di archiviazione

Una firma di accesso condiviso di delega utente offre una protezione superiore a una firma di accesso condiviso con la chiave dell'account di archiviazione. Quando possibile, Microsoft consiglia di usare una firma di accesso condiviso di delega utente. Per altre informazioni, vedere concedere l'accesso limitato ai dati con le firme di accesso condiviso (SAS).

Questo articolo illustra come usare le credenziali Azure Active Directory (Azure AD) per creare una firma di accesso condiviso di delega utente per un contenitore, una directory o un BLOB con la libreria client di archiviazione di Azure per .NET versione 12.

Informazioni sulla firma di accesso condiviso della delega utente

Un token di firma di accesso condiviso per l'accesso a un contenitore o a un BLOB può essere protetto tramite Azure AD credenziali o una chiave dell'account. Una firma di accesso condiviso protetta con credenziali Azure AD viene chiamata firma di accesso condiviso dell'utente, perché il token OAuth 2,0 usato per firmare la firma di accesso condiviso viene richiesto per conto dell'utente.

Microsoft consiglia di utilizzare le credenziali di Azure AD quando possibile come procedura di sicurezza consigliata, anziché utilizzare la chiave dell'account, che può essere compromessa in modo più semplice. Quando la progettazione dell'applicazione richiede firme di accesso condiviso, usare le credenziali Azure AD per creare una firma di accesso condiviso di delega utente per la protezione superiore. Per altre informazioni sulla firma di accesso condiviso della delega utente, vedere creare una firma di accesso condiviso dell'utente.

Attenzione

Qualsiasi client che dispone di una firma di accesso condiviso valida può accedere ai dati nell'account di archiviazione come consentito dalla firma di accesso condiviso. È importante proteggere una firma di accesso condiviso da un utilizzo dannoso o imprevisto. Usare la discrezione per la distribuzione di una firma di accesso condiviso e un piano per la revoca di una firma di accesso condiviso compromessa.

Per altre informazioni sulle firme di accesso condiviso, vedere Concedere accesso limitato alle risorse di archiviazione di Azure tramite firme di accesso condiviso.

Assegnare i ruoli di Azure per l'accesso ai dati

Quando un Azure AD entità di sicurezza tenta di accedere ai dati BLOB, l'entità di sicurezza deve avere le autorizzazioni per la risorsa. Se l'entità di sicurezza è un'identità gestita in Azure o un account utente Azure AD che esegue il codice nell'ambiente di sviluppo, all'entità di sicurezza deve essere assegnato un ruolo di Azure che concede l'accesso ai dati BLOB in archiviazione di Azure. Per informazioni sull'assegnazione delle autorizzazioni tramite il controllo degli accessi in base al ruolo di Azure, vedere la sezione assegnare i ruoli di Azure per i diritti di accesso in autorizzare l'accesso a BLOB e code di Azure con Azure Active Directory.

Installare i pacchetti della libreria client

Nota

Gli esempi illustrati di seguito usano la libreria client di archiviazione di Azure versione 12. La libreria client versione 12 fa parte di Azure SDK. Per altre informazioni su Azure SDK, vedere il repository di Azure SDK su GitHub.

Per installare il pacchetto di archiviazione BLOB, eseguire il comando seguente dalla console di gestione pacchetti NuGet:

Install-Package Azure.Storage.Blobs

Gli esempi illustrati di seguito usano anche la versione più recente della libreria client di identità di Azure per .NET per l'autenticazione con le credenziali Azure ad. Per installare il pacchetto, eseguire il comando seguente dalla console di gestione pacchetti NuGet:

Install-Package Azure.Identity

Per altre informazioni su come eseguire l'autenticazione con la libreria client di identità di Azure da archiviazione di Azure, vedere la sezione eseguire l'autenticazione con la libreria di identità di Azure in autorizzare l'accesso a BLOB e code con Azure Active Directory e identità gestite per le risorse di Azure.

Ottenere le credenziali di un token autenticato

Per ottenere una credenziale token che il codice può usare per autorizzare le richieste ad archiviazione di Azure, creare un'istanza della classe DefaultAzureCredential .

Il frammento di codice seguente mostra come ottenere le credenziali del token autenticato e usarle per creare un client del servizio per l'archiviazione BLOB:

// Construct the blob endpoint from the account name.
string blobEndpoint = string.Format("https://{0}.blob.core.windows.net", accountName);

// Create a new Blob service client with Azure AD credentials.
BlobServiceClient blobClient = new BlobServiceClient(new Uri(blobEndpoint),
                                                     new DefaultAzureCredential());

Ottenere la chiave di delega utente

Ogni firma di accesso condiviso è firmata con una chiave. Per creare una firma di accesso condiviso di delega utente, è necessario prima richiedere una chiave di delega utente, che viene quindi usata per firmare la firma di accesso condiviso. La chiave di delega utente è analoga alla chiave dell'account usata per firmare una firma di accesso condiviso del servizio o una firma di accesso condiviso dell'account, con la differenza che si basa sulle credenziali Azure AD. Quando un client richiede una chiave di delega utente usando un token OAuth 2,0, archiviazione di Azure restituisce la chiave di delega utente per conto dell'utente.

Una volta creata la chiave di delega utente, è possibile usare tale chiave per creare un numero qualsiasi di firme di accesso condiviso per la delega utente, per tutta la durata della chiave. La chiave di delega utente è indipendente dal token OAuth 2,0 usato per acquisirla, pertanto non è necessario rinnovare il token finché la chiave è ancora valida. È possibile specificare che la chiave sia valida per un periodo di un massimo di 7 giorni.

Per richiedere la chiave di delega utente, usare uno dei metodi seguenti:

Il seguente frammento di codice ottiene la chiave di delega dell'utente e ne scrive le proprietà:

// Get a user delegation key for the Blob service that's valid for seven days.
// You can use the key to generate any number of shared access signatures over the lifetime of the key.
UserDelegationKey key = await blobClient.GetUserDelegationKeyAsync(DateTimeOffset.UtcNow,
                                                                   DateTimeOffset.UtcNow.AddDays(7));

// Read the key's properties.
Console.WriteLine("User delegation key properties:");
Console.WriteLine("Key signed start: {0}", key.SignedStartsOn);
Console.WriteLine("Key signed expiry: {0}", key.SignedExpiresOn);
Console.WriteLine("Key signed object ID: {0}", key.SignedObjectId);
Console.WriteLine("Key signed tenant ID: {0}", key.SignedTenantId);
Console.WriteLine("Key signed service: {0}", key.SignedService);
Console.WriteLine("Key signed version: {0}", key.SignedVersion);

Ottenere una firma di accesso condiviso di delega utente per un BLOB

L'esempio di codice seguente illustra il codice completo per l'autenticazione dell'entità di sicurezza e la creazione della firma di accesso condiviso della delega utente per un BLOB:

async static Task<Uri> GetUserDelegationSasBlob(BlobClient blobClient)
{
    BlobServiceClient blobServiceClient =
        blobClient.GetParentBlobContainerClient().GetParentBlobServiceClient();

    // Get a user delegation key for the Blob service that's valid for 7 days.
    // You can use the key to generate any number of shared access signatures 
    // over the lifetime of the key.
    Azure.Storage.Blobs.Models.UserDelegationKey userDelegationKey =
        await blobServiceClient.GetUserDelegationKeyAsync(DateTimeOffset.UtcNow,
                                                          DateTimeOffset.UtcNow.AddDays(7));

    // Create a SAS token that's also valid for 7 days.
    BlobSasBuilder sasBuilder = new BlobSasBuilder()
    {
        BlobContainerName = blobClient.BlobContainerName,
        BlobName = blobClient.Name,
        Resource = "b",
        StartsOn = DateTimeOffset.UtcNow,
        ExpiresOn = DateTimeOffset.UtcNow.AddDays(7)
    };

    // Specify read and write permissions for the SAS.
    sasBuilder.SetPermissions(BlobSasPermissions.Read |
                              BlobSasPermissions.Write);

    // Add the SAS token to the blob URI.
    BlobUriBuilder blobUriBuilder = new BlobUriBuilder(blobClient.Uri)
    {
        // Specify the user delegation key.
        Sas = sasBuilder.ToSasQueryParameters(userDelegationKey, 
                                              blobServiceClient.AccountName)
    };

    Console.WriteLine("Blob user delegation SAS URI: {0}", blobUriBuilder);
    Console.WriteLine();
    return blobUriBuilder.ToUri();
}

Nell'esempio seguente viene verificata la firma di accesso condiviso della delega utente creata nell'esempio precedente da un'applicazione client simulata. Se la firma di accesso condiviso è valida, l'applicazione client è in grado di leggere il contenuto del BLOB. Se la firma di accesso condiviso non è valida, ad esempio se è scaduta, archiviazione di Azure restituisce il codice di errore 403 (accesso negato).

static async Task ReadBlobWithSasAsync(Uri sasUri)
{
    // Try performing a read operation using the blob SAS provided.

    // Create a blob client object for blob operations.
    BlobClient blobClient = new BlobClient(sasUri, null);

    // Download and read the contents of the blob.
    try
    {
        Console.WriteLine("Blob contents:");

        // Download blob contents to a stream and read the stream.
        BlobDownloadInfo blobDownloadInfo = await blobClient.DownloadAsync();
        using (StreamReader reader = new StreamReader(blobDownloadInfo.Content, true))
        {
            string line;
            while ((line = reader.ReadLine()) != null)
            {
                Console.WriteLine(line);
            }
        }

        Console.WriteLine();
        Console.WriteLine("Read operation succeeded for SAS {0}", sasUri);
        Console.WriteLine();
    }
    catch (RequestFailedException e)
    {
        // Check for a 403 (Forbidden) error. If the SAS is invalid, 
        // Azure Storage returns this error.
        if (e.Status == 403)
        {
            Console.WriteLine("Read operation failed for SAS {0}", sasUri);
            Console.WriteLine("Additional error information: " + e.Message);
            Console.WriteLine();
        }
        else
        {
            Console.WriteLine(e.Message);
            Console.ReadLine();
            throw;
        }
    }
}

Ottenere una firma di accesso condiviso di delega utente per un contenitore

Nell'esempio di codice seguente viene illustrato come generare una firma di accesso condiviso di delega utente per un contenitore:

async static Task<Uri> GetUserDelegationSasContainer(BlobContainerClient blobContainerClient)
{
    BlobServiceClient blobServiceClient = blobContainerClient.GetParentBlobServiceClient();

    // Get a user delegation key for the Blob service that's valid for seven days.
    // You can use the key to generate any number of shared access signatures 
    // over the lifetime of the key.
    Azure.Storage.Blobs.Models.UserDelegationKey userDelegationKey =
        await blobServiceClient.GetUserDelegationKeyAsync(DateTimeOffset.UtcNow,
                                                          DateTimeOffset.UtcNow.AddDays(7));

    // Create a SAS token that's also valid for seven days.
    BlobSasBuilder sasBuilder = new BlobSasBuilder()
    {
        BlobContainerName = blobContainerClient.Name,
        Resource = "c",
        StartsOn = DateTimeOffset.UtcNow,
        ExpiresOn = DateTimeOffset.UtcNow.AddDays(7)
    };

    // Specify racwl permissions for the SAS.
    sasBuilder.SetPermissions(
        BlobContainerSasPermissions.Read |
        BlobContainerSasPermissions.Add |
        BlobContainerSasPermissions.Create |
        BlobContainerSasPermissions.Write |
        BlobContainerSasPermissions.List
        );

    // Add the SAS token to the container URI.
    BlobUriBuilder blobUriBuilder = new BlobUriBuilder(blobContainerClient.Uri)
    {
        // Specify the user delegation key.
        Sas = sasBuilder.ToSasQueryParameters(userDelegationKey,
                                              blobServiceClient.AccountName)
    };

    Console.WriteLine("Container user delegation SAS URI: {0}", blobUriBuilder);
    Console.WriteLine();
    return blobUriBuilder.ToUri();
}

Nell'esempio seguente viene verificata la firma di accesso condiviso della delega utente creata nell'esempio precedente da un'applicazione client simulata. Se la firma di accesso condiviso è valida, l'applicazione client è in grado di leggere il contenuto del BLOB. Se la firma di accesso condiviso non è valida, ad esempio se è scaduta, archiviazione di Azure restituisce il codice di errore 403 (accesso negato).

private static async Task ListBlobsWithSasAsync(Uri sasUri)
{
    // Try performing a listing operation using the container SAS provided.

    // Create a container client object for blob operations.
    BlobContainerClient blobContainerClient = new BlobContainerClient(sasUri, null);

    // List blobs in the container.
    try
    {
        // Call the listing operation and return pages of the specified size.
        var resultSegment = blobContainerClient.GetBlobsAsync().AsPages();

        // Enumerate the blobs returned for each page.
        await foreach (Azure.Page<BlobItem> blobPage in resultSegment)
        {
            foreach (BlobItem blobItem in blobPage.Values)
            {
                Console.WriteLine("Blob name: {0}", blobItem.Name);
            }
            Console.WriteLine();
        }

        Console.WriteLine();
        Console.WriteLine("Blob listing operation succeeded for SAS {0}", sasUri);
    }
    catch (RequestFailedException e)
    {
        // Check for a 403 (Forbidden) error. If the SAS is invalid, 
        // Azure Storage returns this error.
        if (e.Status == 403)
        {
            Console.WriteLine("Blob listing operation failed for SAS {0}", sasUri);
            Console.WriteLine("Additional error information: " + e.Message);
            Console.WriteLine();
        }
        else
        {
            Console.WriteLine(e.Message);
            Console.ReadLine();
            throw;
        }
    }
}

Ottenere una firma di accesso condiviso di delega utente per una directory

L'esempio di codice seguente illustra come generare una firma di accesso condiviso di delega utente per una directory quando è abilitato uno spazio dei nomi gerarchico per l'account di archiviazione:

async static Task<Uri> GetUserDelegationSasDirectory(DataLakeDirectoryClient directoryClient)
{
    try
    {
        // Get service endpoint from the directory URI.
        DataLakeUriBuilder dataLakeServiceUri = new DataLakeUriBuilder(directoryClient.Uri)
        {
            FileSystemName = null,
            DirectoryOrFilePath = null
        };

        // Get service client.
        DataLakeServiceClient dataLakeServiceClient =
            new DataLakeServiceClient(dataLakeServiceUri.ToUri(),
                                      new DefaultAzureCredential());

        // Get a user delegation key that's valid for seven days.
        // You can use the key to generate any number of shared access signatures 
        // over the lifetime of the key.
        Azure.Storage.Files.DataLake.Models.UserDelegationKey userDelegationKey =
            await dataLakeServiceClient.GetUserDelegationKeyAsync(DateTimeOffset.UtcNow,
                                                                  DateTimeOffset.UtcNow.AddDays(7));

        // Create a SAS token that's valid for seven days.
        DataLakeSasBuilder sasBuilder = new DataLakeSasBuilder()
        {
            // Specify the file system name and path, and indicate that
            // the client object points to a directory.
            FileSystemName = directoryClient.FileSystemName,
            Resource = "d",
            IsDirectory = true,
            Path = directoryClient.Path,
            ExpiresOn = DateTimeOffset.UtcNow.AddDays(7)
        };

        // Specify racwl permissions for the SAS.
        sasBuilder.SetPermissions(
            DataLakeSasPermissions.Read |
            DataLakeSasPermissions.Add |
            DataLakeSasPermissions.Create |
            DataLakeSasPermissions.Write |
            DataLakeSasPermissions.List
            );

        // Construct the full URI, including the SAS token.
        DataLakeUriBuilder fullUri = new DataLakeUriBuilder(directoryClient.Uri)
        {
            Sas = sasBuilder.ToSasQueryParameters(userDelegationKey,
                                                  dataLakeServiceClient.AccountName)
        };

        Console.WriteLine("Directory user delegation SAS URI: {0}", fullUri);
        Console.WriteLine();
        return fullUri.ToUri();
    }
    catch (Exception e)
    {
        Console.WriteLine(e.Message);
        throw;
    }
}

Nell'esempio seguente viene verificata la firma di accesso condiviso della delega utente creata nell'esempio precedente da un'applicazione client simulata. Se la firma di accesso condiviso è valida, l'applicazione client è in grado di elencare i percorsi dei file per questa directory. Se la firma di accesso condiviso non è valida, ad esempio se è scaduta, archiviazione di Azure restituisce il codice di errore 403 (accesso negato).

private static async Task ListFilesPathsWithDirectorySasAsync(Uri sasUri)
{
    // Try performing an operation using the directory SAS provided.

    // Create a directory client object for listing operations.
    DataLakeDirectoryClient dataLakeDirectoryClient = new DataLakeDirectoryClient(sasUri);

    // List file paths in the directory.
    try
    {
        // Call the listing operation and return pages of the specified size.
        var resultSegment = dataLakeDirectoryClient.GetPathsAsync(false, false).AsPages();

        // Enumerate the file paths returned with each page.
        await foreach (Page<PathItem> pathPage in resultSegment)
        {
            foreach (PathItem pathItem in pathPage.Values)
            {
                Console.WriteLine("File name: {0}", pathItem.Name);
            }
            Console.WriteLine();
        }

        Console.WriteLine();
        Console.WriteLine("Directory listing operation succeeded for SAS {0}", sasUri);
    }
    catch (RequestFailedException e)
    {
        // Check for a 403 (Forbidden) error. If the SAS is invalid, 
        // Azure Storage returns this error.
        if (e.Status == 403)
        {
            Console.WriteLine("Directory listing operation failed for SAS {0}", sasUri);
            Console.WriteLine("Additional error information: " + e.Message);
            Console.WriteLine();
        }
        else
        {
            Console.WriteLine(e.Message);
            Console.ReadLine();
            throw;
        }
    }
}

Risorse per lo sviluppo con .NET

I collegamenti seguenti forniscono risorse utili per gli sviluppatori che usano Libreria client di archiviazione di Azure per .NET.

API comuni di archiviazione di Azure

Api di archiviazione BLOB

Strumenti .NET

Vedi anche