Share via


Usare .NET per gestire gli elenchi di controllo di accesso in Azure Data Lake Archiviazione Gen2

Questo articolo illustra come usare .NET per ottenere, impostare e aggiornare gli elenchi di controllo di accesso di directory e file.

L'ereditarietà ACL è già disponibile per i nuovi elementi figlio creati in una directory padre. Ma è anche possibile aggiungere, aggiornare e rimuovere gli ACL in modo ricorsivo sugli elementi figlio esistenti di una directory padre senza dover apportare queste modifiche singolarmente per ogni elemento figlio.

Riferimento all'API Package (NuGet) | Samples | Gen1 to Gen2 mapping | Give Feedback |

Prerequisiti

  • Una sottoscrizione di Azure. Vedere Ottenere una versione di prova gratuita di Azure.

  • Un account di archiviazione in cui è abilitato lo spazio dei nomi gerarchico. Per crearne uno, seguire queste istruzioni.

  • Interfaccia della riga di comando di Azure versione 2.6.0 o successiva.

  • Una delle autorizzazioni di sicurezza seguenti:

    • Entità di sicurezza microsoft Entra ID di cui è stato effettuato il provisioning a cui è stato assegnato il ruolo proprietario dei dati BLOB Archiviazione, con ambito al contenitore di destinazione, all'account di archiviazione, al gruppo di risorse padre o alla sottoscrizione.

    • Proprietario dell'utente del contenitore o della directory di destinazione a cui si prevede di applicare le impostazioni ACL. Per impostare gli elenchi di controllo di accesso in modo ricorsivo, sono inclusi tutti gli elementi figlio nel contenitore o nella directory di destinazione.

    • Archiviazione chiave dell'account.

Impostare il progetto

Per iniziare, installare Azure.Archiviazione. Pacchetto NuGet Files.DataLake.

  1. Aprire una finestra di comando , ad esempio Windows PowerShell.

  2. Nella directory del progetto installare Azure. Archiviazione. Pacchetto di anteprima Files.DataLake usando il dotnet add package comando .

    dotnet add package Azure.Storage.Files.DataLake -v 12.6.0 -s https://pkgs.dev.azure.com/azure-sdk/public/_packaging/azure-sdk-for-net/nuget/v3/index.json
    

    Aggiungere quindi queste istruzioni using all'inizio del file di codice.

    using Azure;
    using Azure.Core;
    using Azure.Storage;
    using Azure.Storage.Files.DataLake;
    using Azure.Storage.Files.DataLake.Models;
    using System.Collections.Generic;
    using System.Threading.Tasks;
    

Effettuare la connessione all'account

Per usare i frammenti di codice in questo articolo, è necessario creare un'istanza di DataLakeServiceClient che rappresenta l'account di archiviazione.

Connessione utilizzando Microsoft Entra ID

Nota

Se si usa Microsoft Entra ID per autorizzare l'accesso, assicurarsi che all'entità di sicurezza sia stato assegnato il ruolo di proprietario dei dati BLOB Archiviazione. Per altre informazioni sull'applicazione delle autorizzazioni ACL e sugli effetti della modifica, vedere Modello di controllo di accesso in Azure Data Lake Archiviazione Gen2.

È possibile usare la libreria client di identità di Azure per .NET per autenticare l'applicazione con Microsoft Entra ID.

Dopo aver installato il pacchetto, aggiungere questa istruzione using all'inizio del file di codice.

using Azure.Identity;

Prima di tutto, è necessario assegnare uno dei ruoli di controllo degli accessi in base al ruolo di Azure seguenti all'entità di sicurezza:

Ruolo Funzionalità di impostazione ACL
Proprietario dei dati del BLOB di archiviazione Tutte le directory e i file nell'account.
Collaboratore ai dati del BLOB di archiviazione Solo directory e file di proprietà dell'entità di sicurezza.

Creare quindi un'istanza di DataLakeServiceClient e passare una nuova istanza della classe DefaultAzureCredential.

public static DataLakeServiceClient GetDataLakeServiceClient(string accountName)
{
    string dfsUri = $"https://{accountName}.dfs.core.windows.net";

    DataLakeServiceClient dataLakeServiceClient = new DataLakeServiceClient(
        new Uri(dfsUri),
        new DefaultAzureCredential());

    return dataLakeServiceClient;
}

Per altre informazioni sull'uso di DefaultAzureCredential per autorizzare l'accesso ai dati, vedere Come autenticare le applicazioni .NET con i servizi di Azure.

Connessione usando una chiave dell'account

È possibile autorizzare l'accesso ai dati usando le chiavi di accesso dell'account (chiave condivisa). In questo esempio viene creata un'istanza di DataLakeServiceClient autorizzata con la chiave dell'account.

public static DataLakeServiceClient GetDataLakeServiceClient(string accountName, string accountKey)
{
    StorageSharedKeyCredential sharedKeyCredential =
        new StorageSharedKeyCredential(accountName, accountKey);

    string dfsUri = $"https://{accountName}.dfs.core.windows.net";

    DataLakeServiceClient dataLakeServiceClient = new DataLakeServiceClient(
        new Uri(dfsUri),
        sharedKeyCredential);

    return dataLakeServiceClient;
}

Attenzione

L'autorizzazione con chiave condivisa non è consigliata perché potrebbe essere meno sicura. Per una sicurezza ottimale, disabilitare l'autorizzazione tramite chiave condivisa per l'account di archiviazione, come descritto in Impedire l'autorizzazione con chiave condivisa per un account Archiviazione di Azure.

L'uso di chiavi di accesso e stringa di connessione deve essere limitato alle app di verifica iniziali o ai prototipi di sviluppo che non accedono a dati sensibili o di produzione. In caso contrario, le classi di autenticazione basate su token disponibili in Azure SDK devono essere sempre preferite quando si esegue l'autenticazione alle risorse di Azure.

Microsoft consiglia ai client di usare l'ID Microsoft Entra o una firma di accesso condiviso per autorizzare l'accesso ai dati in Archiviazione di Azure. Per altre informazioni, vedere Autorizzare le operazioni per l'accesso ai dati.

Impostare gli elenchi di controllo di accesso

Quando si imposta un elenco di controllo di accesso, sostituire l'intero ACL, incluse tutte le relative voci. Se si vuole modificare il livello di autorizzazione di un'entità di sicurezza o aggiungere una nuova entità di sicurezza all'elenco di controllo di accesso senza influire sulle altre voci esistenti, è consigliabile aggiornare invece l'ACL. Per aggiornare un elenco di controllo di accesso anziché sostituirlo, vedere la sezione Aggiornare gli elenchi di controllo di accesso di questo articolo.

Se si sceglie di impostare l'ACL, è necessario aggiungere una voce per l'utente proprietario, una voce per il gruppo proprietario e una voce per tutti gli altri utenti. Per altre informazioni sull'utente proprietario, sul gruppo proprietario e su tutti gli altri utenti, vedere Utenti e identità.

Questa sezione illustra come:

  • Impostare l'elenco di controllo di accesso di una directory
  • Impostare l'ACL di un file
  • Impostare ricorsivamente gli elenchi di controllo di accesso

Impostare l'elenco di controllo di accesso di una directory

Ottenere l'elenco di controllo di accesso (ACL) di una directory chiamando il metodo DataLakeDirectoryClient.GetAccessControlAsync e impostando l'ACL chiamando il metodo DataLakeDirectoryClient.SetAccessControlList .

Questo esempio ottiene e imposta l'ACL di una directory denominata my-directory. La stringa user::rwx,group::r-x,other::rw- concede all'utente le autorizzazioni di lettura, scrittura ed esecuzione proprietarie, concede al gruppo proprietario solo autorizzazioni di lettura ed esecuzione e concede a tutti gli altri utenti autorizzazioni di lettura e scrittura.

public async Task ManageDirectoryACLs(DataLakeFileSystemClient fileSystemClient)
{
    DataLakeDirectoryClient directoryClient =
      fileSystemClient.GetDirectoryClient("");

    PathAccessControl directoryAccessControl =
        await directoryClient.GetAccessControlAsync();

    foreach (var item in directoryAccessControl.AccessControlList)
    {
        Console.WriteLine(item.ToString());
    }

    IList<PathAccessControlItem> accessControlList
        = PathAccessControlExtensions.ParseAccessControlList
        ("user::rwx,group::r-x,other::rw-");

    directoryClient.SetAccessControlList(accessControlList);

}

È anche possibile ottenere e impostare l'ACL della directory radice di un contenitore. Per ottenere la directory radice, passare una stringa vuota ("") al metodo DataLakeFileSystemClient.GetDirectoryClient .

Impostare l'ACL di un file

Ottenere l'elenco di controllo di accesso (ACL) di un file chiamando il metodo DataLakeFileClient.GetAccessControlAsync e impostando l'ACL chiamando il metodo DataLakeFileClient.SetAccessControlList .

Questo esempio ottiene e imposta l'ACL di un file denominato my-file.txt. La stringa user::rwx,group::r-x,other::rw- concede all'utente le autorizzazioni di lettura, scrittura ed esecuzione proprietarie, concede al gruppo proprietario solo autorizzazioni di lettura ed esecuzione e concede a tutti gli altri utenti autorizzazioni di lettura e scrittura.

public async Task ManageFileACLs(DataLakeFileSystemClient fileSystemClient)
{
    DataLakeDirectoryClient directoryClient =
        fileSystemClient.GetDirectoryClient("my-directory");

    DataLakeFileClient fileClient =
        directoryClient.GetFileClient("hello.txt");

    PathAccessControl FileAccessControl =
        await fileClient.GetAccessControlAsync();

    foreach (var item in FileAccessControl.AccessControlList)
    {
        Console.WriteLine(item.ToString());
    }

    IList<PathAccessControlItem> accessControlList
        = PathAccessControlExtensions.ParseAccessControlList
        ("user::rwx,group::r-x,other::rw-");

    fileClient.SetAccessControlList(accessControlList);
}

Impostare ricorsivamente gli elenchi di controllo di accesso

Impostare gli ACL in modo ricorsivo chiamando il metodo DataLakeDirectoryClient.SetAccessControlRecursiveAsync . Passare questo metodo a List of PathAccessControlItem. Ogni PathAccessControlItem definisce una voce ACL.

Se si desidera impostare una voce ACL predefinita , è possibile impostare la proprietà PathAccessControlItem.DefaultScope di PathAccessControlItem su true.

In questo esempio viene impostato l'elenco di controllo di accesso di una directory denominata my-parent-directory. Questo metodo accetta un parametro booleano denominato isDefaultScope che specifica se impostare l'ACL predefinito. Tale parametro viene usato nel costruttore di PathAccessControlItem. Le voci dell'ACL forniscono all'utente proprietario le autorizzazioni di lettura, scrittura ed esecuzione, assegnano al gruppo proprietario solo le autorizzazioni di lettura ed esecuzione e concede a tutti gli altri utenti nessun accesso. L'ultima voce ACL in questo esempio fornisce a un utente specifico le autorizzazioni di lettura ed esecuzione dell'ID xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx oggetto.

    public async Task SetACLRecursively(DataLakeServiceClient serviceClient, bool isDefaultScope)
{
    DataLakeDirectoryClient directoryClient =
        serviceClient.GetFileSystemClient("my-container").
            GetDirectoryClient("my-parent-directory");

    List<PathAccessControlItem> accessControlList =
        new List<PathAccessControlItem>()
    {
new PathAccessControlItem(AccessControlType.User,
    RolePermissions.Read |
    RolePermissions.Write |
    RolePermissions.Execute, isDefaultScope),

new PathAccessControlItem(AccessControlType.Group,
    RolePermissions.Read |
    RolePermissions.Execute, isDefaultScope),

new PathAccessControlItem(AccessControlType.Other,
    RolePermissions.None, isDefaultScope),

new PathAccessControlItem(AccessControlType.User,
    RolePermissions.Read |
    RolePermissions.Execute, isDefaultScope,
    entityId: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"),
    };

    await directoryClient.SetAccessControlRecursiveAsync
        (accessControlList, null);
}

Aggiornare gli elenchi di controllo di accesso

Quando si aggiorna un ACL, si modifica l'ACL anziché sostituire l'ACL. Ad esempio, è possibile aggiungere una nuova entità di sicurezza all'elenco di controllo di accesso senza influire sulle altre entità di sicurezza elencate nell'elenco di controllo di accesso. Per sostituire l'ACL invece di aggiornarlo, vedere la sezione Impostare elenchi di controllo di accesso di questo articolo.

Questa sezione illustra come:

  • Aggiornare un ACL
  • Aggiornare gli elenchi di controllo di accesso in modo ricorsivo

Aggiornare un ACL

Prima di tutto, ottenere l'ACL di una directory chiamando il metodo DataLakeDirectoryClient.GetAccessControlAsync . Copiare l'elenco di voci ACL in un nuovo elenco di oggetti PathAccessControl . Individuare quindi la voce da aggiornare e sostituirla nell'elenco. Impostare l'ACL chiamando il metodo DataLakeDirectoryClient.SetAccessControlList .

Questo esempio aggiorna l'ACL radice di un contenitore sostituendo la voce ACL per tutti gli altri utenti.

public async Task UpdateDirectoryACLs(DataLakeFileSystemClient fileSystemClient)
{
    DataLakeDirectoryClient directoryClient =
      fileSystemClient.GetDirectoryClient("");

    PathAccessControl directoryAccessControl =
        await directoryClient.GetAccessControlAsync();

    List<PathAccessControlItem> accessControlListUpdate 
        = (List<PathAccessControlItem>)directoryAccessControl.AccessControlList;

    int index = -1;

    foreach (var item in accessControlListUpdate)
    {
        if (item.AccessControlType == AccessControlType.Other)
        {
            index = accessControlListUpdate.IndexOf(item);
            break;
        }
    }

    if (index > -1)
    {
        accessControlListUpdate[index] = new PathAccessControlItem(AccessControlType.Other,
        RolePermissions.Read |
        RolePermissions.Execute);

        directoryClient.SetAccessControlList(accessControlListUpdate);
    }

   }

Aggiornare gli elenchi di controllo di accesso in modo ricorsivo

Per aggiornare un ACL in modo ricorsivo, creare un nuovo oggetto ACL con la voce ACL da aggiornare e quindi usare tale oggetto nell'operazione di aggiornamento ACL. Non ottenere l'ACL esistente, specificare solo le voci ACL da aggiornare.

Aggiornare un elenco di controllo di accesso in modo ricorsivo chiamando il metodo DataLakeDirectoryClient.UpdateAccessControlRecursiveAsync . Passare questo metodo a List of PathAccessControlItem. Ogni PathAccessControlItem definisce una voce ACL.

Se si desidera aggiornare una voce ACL predefinita , è possibile impostare la proprietà PathAccessControlItem.DefaultScope di PathAccessControlItem su true.

In questo esempio viene aggiornata una voce ACL con autorizzazione di scrittura. Questo metodo accetta un parametro booleano denominato isDefaultScope che specifica se aggiornare l'ACL predefinito. Tale parametro viene usato nel costruttore di PathAccessControlItem.

public async Task UpdateACLsRecursively(DataLakeServiceClient serviceClient, bool isDefaultScope)
{
    DataLakeDirectoryClient directoryClient =
        serviceClient.GetFileSystemClient("my-container").
        GetDirectoryClient("my-parent-directory");

    List<PathAccessControlItem> accessControlListUpdate =
        new List<PathAccessControlItem>()
    {
new PathAccessControlItem(AccessControlType.User,
    RolePermissions.Read |
    RolePermissions.Write |
    RolePermissions.Execute, isDefaultScope,
    entityId: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"),
    };

    await directoryClient.UpdateAccessControlRecursiveAsync
        (accessControlListUpdate, null);

}

Rimuovere le voci ACL

È possibile rimuovere una o più voci ACL. Questa sezione illustra come:

  • Rimuovere una voce ACL
  • Rimuovere le voci ACL in modo ricorsivo

Rimuovere una voce ACL

Prima di tutto, ottenere l'ACL di una directory chiamando il metodo DataLakeDirectoryClient.GetAccessControlAsync . Copiare l'elenco di voci ACL in un nuovo elenco di oggetti PathAccessControl . Individuare quindi la voce che si desidera rimuovere e chiamare il metodo Remove della raccolta. Impostare l'ACL aggiornato chiamando il metodo DataLakeDirectoryClient.SetAccessControlList .

Questo esempio aggiorna l'ACL radice di un contenitore sostituendo la voce ACL per tutti gli altri utenti.

public async Task RemoveDirectoryACLEntry
    (DataLakeFileSystemClient fileSystemClient)
{
    DataLakeDirectoryClient directoryClient =
      fileSystemClient.GetDirectoryClient("");

    PathAccessControl directoryAccessControl =
        await directoryClient.GetAccessControlAsync();

    List<PathAccessControlItem> accessControlListUpdate
        = (List<PathAccessControlItem>)directoryAccessControl.AccessControlList;

    PathAccessControlItem entryToRemove = null;

    foreach (var item in accessControlListUpdate)
    {
        if (item.EntityId == "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")
        {
            entryToRemove = item;
            break;
        }
    }

    if (entryToRemove != null)
    {
        accessControlListUpdate.Remove(entryToRemove);
        directoryClient.SetAccessControlList(accessControlListUpdate);
    }

}

Rimuovere le voci ACL in modo ricorsivo

Per rimuovere le voci ACL in modo ricorsivo, creare un nuovo oggetto ACL per la voce ACL da rimuovere e quindi usare tale oggetto nell'operazione di rimozione dell'elenco di controllo di accesso. Non ottenere l'ACL esistente, specificare solo le voci ACL da rimuovere.

Rimuovere le voci ACL chiamando il metodo DataLakeDirectoryClient.RemoveAccessControlRecursiveAsync . Passare questo metodo a List of PathAccessControlItem. Ogni PathAccessControlItem definisce una voce ACL.

Se si desidera rimuovere una voce ACL predefinita , è possibile impostare la proprietà PathAccessControlItem.DefaultScope di PathAccessControlItem su true.

In questo esempio viene rimossa una voce ACL dall'ACL della directory denominata my-parent-directory. Questo metodo accetta un parametro booleano denominato isDefaultScope che specifica se rimuovere la voce dall'ACL predefinito. Tale parametro viene usato nel costruttore di PathAccessControlItem.

public async Task RemoveACLsRecursively(DataLakeServiceClient serviceClient, bool isDefaultScope)
{
    DataLakeDirectoryClient directoryClient =
        serviceClient.GetFileSystemClient("my-container").
            GetDirectoryClient("my-parent-directory");

    List<RemovePathAccessControlItem> accessControlListForRemoval =
        new List<RemovePathAccessControlItem>()
        {
    new RemovePathAccessControlItem(AccessControlType.User, isDefaultScope,
    entityId: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"),
        };

    await directoryClient.RemoveAccessControlRecursiveAsync
        (accessControlListForRemoval, null);

}

Ripristino da errori

È possibile che si verifichino errori di runtime o di autorizzazione durante la modifica degli elenchi di controllo di accesso in modo ricorsivo. Per gli errori di runtime, riavviare il processo dall'inizio. Gli errori di autorizzazione possono verificarsi se l'entità di sicurezza non dispone di autorizzazioni sufficienti per modificare l'elenco di controllo di accesso di una directory o di un file presente nella gerarchia di directory da modificare. Risolvere il problema di autorizzazione e quindi scegliere di riprendere il processo dal punto di errore usando un token di continuazione o riavviare il processo dall'inizio. Non è necessario usare il token di continuazione se si preferisce riavviare dall'inizio. È possibile riapplicare le voci ACL senza alcun impatto negativo.

In questo esempio viene restituito un token di continuazione in caso di errore. L'applicazione può chiamare di nuovo questo metodo di esempio dopo aver risolto l'errore e passare il token di continuazione. Se questo metodo di esempio viene chiamato per la prima volta, l'applicazione può passare un valore di per il parametro del token di null continuazione.

public async Task<string> ResumeAsync(DataLakeServiceClient serviceClient,
    DataLakeDirectoryClient directoryClient,
    List<PathAccessControlItem> accessControlList,
    string continuationToken)
{
    try
    {
        var accessControlChangeResult =
            await directoryClient.SetAccessControlRecursiveAsync(
                accessControlList, continuationToken: continuationToken, null);

        if (accessControlChangeResult.Value.Counters.FailedChangesCount > 0)
        {
            continuationToken =
                accessControlChangeResult.Value.ContinuationToken;
        }

        return continuationToken;
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.ToString());
        return continuationToken;
    }

}

Se si desidera che il processo venga completato senza interruzioni dagli errori di autorizzazione, è possibile specificarlo.

Per assicurarsi che il processo venga completato senza interruzioni, passare un oggetto AccessControlChangedOptions e impostare la proprietà ContinueOnFailure dell'oggetto su true.

Questo esempio imposta le voci ACL in modo ricorsivo. Se questo codice rileva un errore di autorizzazione, registra l'errore e continua l'esecuzione. In questo esempio viene stampato il numero di errori nella console.

public async Task ContinueOnFailureAsync(DataLakeServiceClient serviceClient,
    DataLakeDirectoryClient directoryClient,
    List<PathAccessControlItem> accessControlList)
{
    var accessControlChangeResult =
        await directoryClient.SetAccessControlRecursiveAsync(
            accessControlList, null, new AccessControlChangeOptions()
            { ContinueOnFailure = true });

    var counters = accessControlChangeResult.Value.Counters;

    Console.WriteLine("Number of directories changed: " +
        counters.ChangedDirectoriesCount.ToString());

    Console.WriteLine("Number of files changed: " +
        counters.ChangedFilesCount.ToString());

    Console.WriteLine("Number of failures: " +
        counters.FailedChangesCount.ToString());
}

Procedure consigliate

Questa sezione fornisce alcune linee guida sulle procedure consigliate per l'impostazione degli elenchi di controllo di accesso in modo ricorsivo.

Gestione degli errori di runtime

Un errore di runtime può verificarsi per molti motivi (ad esempio, un'interruzione o un problema di connettività client). Se si verifica un errore di runtime, riavviare il processo ACL ricorsivo. Gli elenchi di controllo di accesso possono essere riapplicati agli elementi senza causare un impatto negativo.

Gestione degli errori di autorizzazione (403)

Se si verifica un'eccezione di controllo di accesso durante l'esecuzione di un processo ACL ricorsivo, l'entità di sicurezza di Active Directory potrebbe non disporre di autorizzazioni sufficienti per applicare un elenco di controllo di accesso a uno o più elementi figlio nella gerarchia di directory. Quando si verifica un errore di autorizzazione, il processo viene arrestato e viene fornito un token di continuazione. Risolvere il problema di autorizzazione e quindi usare il token di continuazione per elaborare il set di dati rimanente. Le directory e i file che sono già stati elaborati correttamente non dovranno essere elaborati di nuovo. È anche possibile scegliere di riavviare il processo ACL ricorsivo. Gli elenchi di controllo di accesso possono essere riapplicati agli elementi senza causare un impatto negativo.

Credenziali

È consigliabile effettuare il provisioning di un'entità di sicurezza Di Microsoft Entra assegnata al ruolo proprietario dei dati BLOB Archiviazione nell'ambito dell'account di archiviazione o del contenitore di destinazione.

Prestazioni

Per ridurre la latenza, è consigliabile eseguire il processo ACL ricorsivo in una macchina virtuale di Azure che si trova nella stessa area dell'account di archiviazione.

Limiti ACL

Il numero massimo di ACL che è possibile applicare a una directory o a un file è 32 ACL di accesso e 32 ACL predefiniti. Per altre informazioni, vedere Access control in Azure Data Lake Storage Gen2 (Controllo di accesso in Azure Data Lake Storage Gen2).

Vedi anche