Använda Python för att hantera ACL:er i Azure Data Lake Storage Gen2

Den här artikeln visar hur du använder Python för att hämta, ange och uppdatera åtkomstkontrolllistorna med kataloger och filer.

ACL-arv är redan tillgängligt för nya underordnade objekt som skapas under en överordnad katalog. Men du kan också lägga till, uppdatera och ta bort ACL:er rekursivt på befintliga underordnade objekt i en överordnad katalog utan att behöva göra dessa ändringar individuellt för varje underordnat objekt.

Paket (Python-paketindex) | Exempel | Rekursiva ACL-exempel | API-referens | Gen1 till Gen2-mappning | Ge feedback

Förutsättningar

  • En Azure-prenumeration. Mer information finns i Hämta en kostnadsfri utvärderingsversion av Azure.

  • Ett lagringskonto som har hierarkisk namnrymd (HNS) aktiverat. Följ de här anvisningarna för att skapa en.

  • Azure CLI-version 2.6.0 eller senare.

  • En av följande säkerhetsbehörigheter:

    • Ett etablerat Azure Active Directory-säkerhetsobjekt (AD) som har tilldelats rollen Storage Blob Data-ägare i omfånget för antingen målcontainern, den överordnade resursgruppen eller prenumerationen.

    • Äger användaren av målcontainern eller målkatalogen som du planerar att tillämpa ACL-inställningar på. Om du vill ange ACL:er rekursivt inkluderar detta alla underordnade objekt i målcontainern eller målkatalogen.

    • Storage kontonyckel.

Konfigurera projektet

Installera Azure Data Lake Storage-klientbiblioteket för Python med hjälp av pip.

pip install azure-storage-file-datalake

Lägg till dessa importutdrag överst i kodfilen.

import os, uuid, sys
from azure.storage.filedatalake import DataLakeServiceClient
from azure.core._match_conditions import MatchConditions
from azure.storage.filedatalake._models import ContentSettings

Anslut till kontot

Om du vill använda kodfragmenten i den här artikeln måste du skapa en DataLakeServiceClient-instans som representerar lagringskontot.

Anslut med hjälp av Azure Active Directory (AD)

Anteckning

Om du använder Azure Active Directory (Azure AD) för att auktorisera åtkomst kontrollerar du att ditt säkerhetsobjekt har tilldelats rollen Storage blobdataägare. Mer information om hur ACL-behörigheter tillämpas och effekterna av att ändra dem finns i Access control model in Azure Data Lake Storage Gen2 (Åtkomstkontrollmodell i Azure Data Lake Storage Gen2).

Du kan använda Azure Identity-klientbiblioteket för Python för att autentisera ditt program med Azure AD.

Hämta ett klient-ID, en klienthemlighet och ett klientorganisations-ID. Information om hur du gör detta finns i Hämta en token från Azure AD för auktorisering av begäranden från ett klientprogram. Som en del av den processen måste du tilldela någon av följande Roller för rollbaserad åtkomstkontroll (Azure RBAC) i Azure till ditt säkerhetsobjekt.

Roll Funktion för ACL-inställning
Storage Blob Data-ägare Alla kataloger och filer i kontot.
Storage Blob Data-deltagare Endast kataloger och filer som ägs av säkerhetsobjekt.

I det här exemplet skapas en DataLakeServiceClient-instans med hjälp av ett klient-ID, en klienthemlighet och ett klientorganisations-ID.

def initialize_storage_account_ad(storage_account_name, client_id, client_secret, tenant_id):
    
    try:  
        global service_client

        credential = ClientSecretCredential(tenant_id, client_id, client_secret)

        service_client = DataLakeServiceClient(account_url="{}://{}.dfs.core.windows.net".format(
            "https", storage_account_name), credential=credential)
    
    except Exception as e:
        print(e)

Anteckning

Fler exempel finns i dokumentationen om Azure Identity-klientbiblioteket för Python.

Anslut med hjälp av en kontonyckel

Det här är det enklaste sättet att ansluta till ett konto.

I det här exemplet skapas en DataLakeServiceClient-instans med hjälp av en kontonyckel.

def initialize_storage_account(storage_account_name, storage_account_key):
    
    try:  
        global service_client

        service_client = DataLakeServiceClient(account_url="{}://{}.dfs.core.windows.net".format(
            "https", storage_account_name), credential=storage_account_key)
    
    except Exception as e:
        print(e)
  • Ersätt platshållarvärdet storage_account_name med namnet på ditt lagringskonto.

  • Ersätt storage_account_key platshållarvärdet med åtkomstnyckeln för lagringskontot.

Ange ACL:er

När du anger en ACL ersätter du hela ACL:en, inklusive alla dess poster. Om du vill ändra behörighetsnivån för ett säkerhetsobjekt eller lägga till ett nytt säkerhetsobjekt till ACL:en utan att påverka andra befintliga poster, bör du uppdatera ACL:en i stället. Information om hur du uppdaterar en ACL i stället för att ersätta den finns i avsnittet Uppdatera ACL:er i den här artikeln.

Det här avsnittet visar hur du:

  • Ange ACL för en katalog
  • Ange ACL för en fil

Ange ACL för en katalog

Hämta åtkomstkontrollista (ACL) för en katalog genom att anropa DataLakeDirectoryClient.get_access_control och ange ACL genom att anropa DataLakeDirectoryClient.set_access_control metoden.

Det här exemplet hämtar och anger ACL för en katalog med namnet my-directory . Strängen ger den äger användaren läs-, skriv- och körningsbehörigheter, ger den egna gruppen endast läs- och körningsbehörigheter och ger alla andra läs- rwxr-xrw- och skrivbehörighet.

def manage_directory_permissions():
    try:
        file_system_client = service_client.get_file_system_client(file_system="my-file-system")

        directory_client = file_system_client.get_directory_client("my-directory")
        
        acl_props = directory_client.get_access_control()
        
        print(acl_props['permissions'])
        
        new_dir_permissions = "rwxr-xrw-"
        
        directory_client.set_access_control(permissions=new_dir_permissions)
        
        acl_props = directory_client.get_access_control()
        
        print(acl_props['permissions'])
    
    except Exception as e:
     print(e)

Du kan också hämta och ange ACL för rotkatalogen för en container. Hämta rotkatalogen genom att anropa FileSystemClient._get_root_directory_client-metoden.

Ange ACL för en fil

Hämta åtkomstkontrollista (ACL) för en fil genom att anropa DataLakeFileClient.get_access_control och ange ACL genom att anropa DataLakeFileClient.set_access_control metoden.

Det här exemplet hämtar och anger ACL för en fil med namnet my-file.txt . Strängen ger den äger användaren läs-, skriv- och körningsbehörigheter, ger den egna gruppen endast läs- och körningsbehörigheter och ger alla andra läs- rwxr-xrw- och skrivbehörighet.

def manage_file_permissions():
    try:
        file_system_client = service_client.get_file_system_client(file_system="my-file-system")

        directory_client = file_system_client.get_directory_client("my-directory")
        
        file_client = directory_client.get_file_client("uploaded-file.txt")

        acl_props = file_client.get_access_control()
        
        print(acl_props['permissions'])
        
        new_file_permissions = "rwxr-xrw-"
        
        file_client.set_access_control(permissions=new_file_permissions)
        
        acl_props = file_client.get_access_control()
        
        print(acl_props['permissions'])

    except Exception as e:
     print(e)

Ange ACL:er rekursivt

När du anger en ACL ersätter du hela ACL:en, inklusive alla dess poster. Om du vill ändra behörighetsnivån för ett säkerhetsobjekt eller lägga till ett nytt säkerhetsobjekt till ACL:en utan att påverka andra befintliga poster, bör du uppdatera ACL:en i stället. Information om hur du uppdaterar en ACL i stället för att ersätta den finns i avsnittet Uppdatera ACL:er rekursivt i den här artikeln.

Ange ACL:er rekursivt genom att anropa DataLakeDirectoryClient.set_access_control_recursive-metoden.

Om du vill ange en standardpost för ACL lägger du till strängen default: i början av varje ACL-poststräng.

I det här exemplet anges ACL för en katalog med namnet my-parent-directory .

Den här metoden accepterar en boolesk parameter med is_default_scope namnet som anger om standard-ACL ska anges. Om den parametern är föregås listan med True ACL-poster med strängen default: .

Posterna i ACL ger den äger användaren läs-, skriv- och körbehörigheter, ger den egna gruppen endast läs- och körningsbehörigheter och ger alla andra ingen åtkomst. Den sista ACL-posten i det här exemplet ger en specifik användare med objekt-ID:t ""xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" läs- och körningsbehörigheter. De här posterna ger den äger användaren läs-, skriv- och körningsbehörigheter, ger den egna gruppen endast läs- och körningsbehörigheter och ger alla andra ingen åtkomst. Den sista ACL-posten i det här exemplet ger en specifik användare med objekt-ID:t ""xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" läs- och körningsbehörigheter.

def set_permission_recursively(is_default_scope):
    
    try:
        file_system_client = service_client.get_file_system_client(file_system="my-container")

        directory_client = file_system_client.get_directory_client("my-parent-directory")

        acl = 'user::rwx,group::rwx,other::rwx,user:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx:r--'   

        if is_default_scope:
           acl = 'default:user::rwx,default:group::rwx,default:other::rwx,default:user:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx:r--'

        directory_client.set_access_control_recursive(acl=acl)
        
        acl_props = directory_client.get_access_control()
        
        print(acl_props['permissions'])

    except Exception as e:
     print(e)

Ett exempel som bearbetar ACL:er rekursivt i batchar genom att ange en batchstorlek finns i Python-exemplet.

Uppdatera ACL:er rekursivt

När du uppdaterar en ACL ändrar du ACL:en i stället för att ersätta ACL:en. Du kan till exempel lägga till ett nytt säkerhetsobjekt i ACL:en utan att påverka andra säkerhetsobjekt som anges i ACL:en. Information om hur du ersätter ACL:en i stället för att uppdatera den finns i avsnittet Ange ACL:er i den här artikeln.

Om du vill uppdatera en ACL rekursivt skapar du ett nytt ACL-objekt med den ACL-post som du vill uppdatera och använder sedan objektet i åtgärden uppdatera ACL. Hämta inte den befintliga ACL:en, ange bara ACL-poster som ska uppdateras. Uppdatera en ACL rekursivt genom att anropa DataLakeDirectoryClient.update_access_control_recursive-metoden. Om du vill uppdatera en standardpost för ACL lägger du till strängen default: i början av varje ACL-poststräng.

I det här exemplet uppdateras en ACL-post med skrivbehörighet.

I det här exemplet anges ACL för en katalog med namnet my-parent-directory . Den här metoden accepterar en boolesk parameter med is_default_scope namnet som anger om standard-ACL:en ska uppdateras. Om parametern är True föregås den uppdaterade ACL-posten av strängen default: .

def update_permission_recursively(is_default_scope):
    
    try:
        file_system_client = service_client.get_file_system_client(file_system="my-container")

        directory_client = file_system_client.get_directory_client("my-parent-directory")
              
        acl = 'user:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx:rwx'   

        if is_default_scope:
           acl = 'default:user:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx:rwx'

        directory_client.update_access_control_recursive(acl=acl)

        acl_props = directory_client.get_access_control()
        
        print(acl_props['permissions'])

    except Exception as e:
     print(e)

Ett exempel som bearbetar ACL:er rekursivt i batchar genom att ange en batchstorlek finns i Python-exemplet.

Ta bort ACL-poster rekursivt

Du kan ta bort en eller flera ACL-poster. Om du vill ta bort ACL-poster rekursivt skapar du ett nytt ACL-objekt för ACL-posten som ska tas bort och använder sedan objektet i åtgärden ta bort ACL. Hämta inte den befintliga ACL:en, ange bara de ACL-poster som ska tas bort.

Ta bort ACL-poster genom att anropa DataLakeDirectoryClient.remove_access_control_recursive-metoden. Om du vill ta bort en standardpost för ACL lägger du till default: strängen i början av ACL-poststrängen.

Det här exemplet tar bort en ACL-post från ACL för katalogen med namnet my-parent-directory . Den här metoden accepterar en boolesk parameter med is_default_scope namnet som anger om posten ska tas bort från standard-ACL:en. Om parametern är True föregås den uppdaterade ACL-posten av strängen default: .

def remove_permission_recursively(is_default_scope):

    try:
        file_system_client = service_client.get_file_system_client(file_system="my-container")

        directory_client = file_system_client.get_directory_client("my-parent-directory")

        acl = 'user:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'

        if is_default_scope:
           acl = 'default:user:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'

        directory_client.remove_access_control_recursive(acl=acl)

    except Exception as e:
     print(e)

Ett exempel som bearbetar ACL:er rekursivt i batchar genom att ange en batchstorlek finns i Python-exemplet.

Återställa från fel

Du kan stöta på körnings- eller behörighetsfel. Starta om processen från början för körningsfel. Behörighetsfel kan inträffa om säkerhetsobjekt inte har tillräcklig behörighet för att ändra ACL för en katalog eller fil som finns i kataloghierarkin som ändras. Åtgärda behörighetsproblemet och välj sedan att antingen återuppta processen från felpunkten genom att använda en fortsättningstoken eller starta om processen från början. Du behöver inte använda fortsättningstoken om du föredrar att starta om från början. Du kan tillämpa ACL-poster igen utan någon negativ inverkan.

Det här exemplet returnerar en fortsättningstoken i händelse av ett fel. Programmet kan anropa den här exempelmetoden igen när felet har åtgärdats och skicka in fortsättningstoken. Om den här exempelmetoden anropas för första gången kan programmet skicka ett värde för för None fortsättningstokenparametern.

def resume_set_acl_recursive(continuation_token):
    
    try:
        file_system_client = service_client.get_file_system_client(file_system="my-container")

        directory_client = file_system_client.get_directory_client("my-parent-directory")
              
        acl = 'user::rwx,group::rwx,other::rwx,user:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx:r--'

        acl_change_result = directory_client.set_access_control_recursive(acl=acl, continuation=continuation_token)

        continuation_token = acl_change_result.continuation

        return continuation_token
        
    except Exception as e:
     print(e) 
     return continuation_token

Ett exempel som bearbetar ACL:er rekursivt i batchar genom att ange en batchstorlek finns i Python-exemplet.

Om du vill att processen ska slutföras utan avbrott av behörighetsfel kan du ange det.

För att säkerställa att processen slutförs utan avbrott ska du inte skicka en fortsättningstoken till DataLakeDirectoryClient.set_access_control_recursive-metoden.

I det här exemplet anges ACL-poster rekursivt. Om den här koden påträffar ett behörighetsfel registrerar den felet och fortsätter körningen. Det här exemplet skriver ut antalet fel till konsolen.

def continue_on_failure():
    
    try:
        file_system_client = service_client.get_file_system_client(file_system="my-container")

        directory_client = file_system_client.get_directory_client("my-parent-directory")
              
        acl = 'user::rwx,group::rwx,other::rwx,user:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx:r--'

        acl_change_result = directory_client.set_access_control_recursive(acl=acl)

        print("Summary: {} directories and {} files were updated successfully, {} failures were counted."
          .format(acl_change_result.counters.directories_successful, acl_change_result.counters.files_successful,
                  acl_change_result.counters.failure_count))
        
    except Exception as e:
     print(e)

Ett exempel som bearbetar ACL:er rekursivt i batchar genom att ange en batchstorlek finns i Python-exemplet.

Bästa praxis

Det här avsnittet innehåller rikt linjer för bästa praxis för att ställa in ACL: er rekursivt.

Hantera körnings fel

Ett körnings fel kan uppstå i många olika orsaker (till exempel: ett avbrott eller problem med klient anslutning). Om du stöter på ett körnings fel startar du om den rekursiva ACL-processen. ACL: er kan återanvändas på objekt utan att orsaka negativ påverkan.

Hantering av behörighets fel (403)

Om du stöter på ett åtkomst kontroll undantag när du kör en rekursiv ACL-process kanske ditt säkerhets objekt i AD inte har tillräcklig behörighet för att tillämpa en ACL på ett eller flera av de underordnade objekten i mapphierarkin. När ett behörighets fel inträffar stoppas processen och en fortsättnings-token anges. Åtgärda behörighets problemet och Använd sedan den fortsättnings-token för att bearbeta den återstående data mängden. De kataloger och filer som redan har bearbetats behöver inte bearbetas igen. Du kan också välja att starta om den rekursiva ACL-processen. ACL: er kan återanvändas på objekt utan att orsaka negativ påverkan.

Autentiseringsuppgifter

Vi rekommenderar att du etablerar ett säkerhets objekt för Azure AD som har tilldelats rollen som lagrings-BLOB-dataägare i omfånget för mål lagrings kontot eller behållaren.

Prestanda

För att minska svars tiden rekommenderar vi att du kör den rekursiva ACL-processen på en virtuell Azure-dator (VM) som finns i samma region som ditt lagrings konto.

ACL-gränser

Det maximala antalet ACL: er som du kan tillämpa på en katalog eller fil är 32 åtkomst-ACL: er och 32 standard-ACL: er. Mer information finns i Åtkomstkontroll i Azure Data Lake Storage Gen2.

Se även