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 åtkomstkontrollistor 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.

Package (Python Package Index) | Samples | Recursive ACL samples | API reference | Gen1 to Gen2 mapping | Give Feedback

Förutsättningar

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

  • Ett lagringskonto med hierarkisk namnrymd (HNS) aktiverat. Följ dessa instruktioner för att skapa en.

  • Azure CLI-version 2.6.0 eller senare.

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

    • Ett etablerat Säkerhetsobjekt för Microsoft Entra-ID som har tilldelats rollen Lagringsblobdataägare, som är begränsad till målcontainern, lagringskontot, den överordnade resursgruppen eller prenumerationen.

    • Ägande användare av målcontainern eller katalogen 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 katalogen.

    • Lagringskontonyckel.

Konfigurera projektet

Installera Azure Data Lake Storage-klientbiblioteket för Python med pip.

pip install azure-storage-file-datalake

Lägg till dessa importinstruktioner överst i kodfilen.

from azure.storage.filedatalake import DataLakeServiceClient
from azure.identity import DefaultAzureCredential

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 Microsoft Entra-ID

Kommentar

Om du använder Microsoft Entra-ID för att auktorisera åtkomst kontrollerar du att ditt säkerhetsobjekt har tilldelats rollen Lagringsblobdataägare. Mer information om hur ACL-behörigheter tillämpas och hur du ändrar dem finns i Åtkomstkontrollmodell i Azure Data Lake Storage Gen2.

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

Först måste du tilldela någon av följande rollbaserade åtkomstkontrollroller i Azure (Azure RBAC) till ditt säkerhetsobjekt:

Roll ACL-inställningsfunktion
Storage Blob Data-ägare Alla kataloger och filer i kontot.
Storage Blob Data-deltagare Endast kataloger och filer som ägs av säkerhetsobjektet.

Skapa sedan en DataLakeServiceClient-instans och skicka in en ny instans av klassen DefaultAzureCredential .

def get_service_client_token_credential(self, account_name) -> DataLakeServiceClient:
    account_url = f"https://{account_name}.dfs.core.windows.net"
    token_credential = DefaultAzureCredential()

    service_client = DataLakeServiceClient(account_url, credential=token_credential)

    return service_client

Mer information om hur du använder DefaultAzureCredential för att auktorisera åtkomst till data finns i Översikt: Autentisera Python-appar till Azure med Hjälp av Azure SDK.

Anslut med hjälp av en kontonyckel

Du kan auktorisera åtkomst till data med hjälp av dina kontoåtkomstnycklar (delad nyckel). I det här exemplet skapas en DataLakeServiceClient-instans som är auktoriserad med kontonyckeln.

def get_service_client_account_key(self, account_name, account_key) -> DataLakeServiceClient:
    account_url = f"https://{account_name}.dfs.core.windows.net"
    service_client = DataLakeServiceClient(account_url, credential=account_key)

    return service_client

Varning

Auktorisering med delad nyckel rekommenderas inte eftersom det kan vara mindre säkert. För optimal säkerhet inaktiverar du auktorisering via delad nyckel för ditt lagringskonto enligt beskrivningen i Förhindra auktorisering av delad nyckel för ett Azure Storage-konto.

Användning av åtkomstnycklar och anslutningssträng bör begränsas till inledande konceptbevisappar eller utvecklingsprototyper som inte har åtkomst till produktion eller känsliga data. Annars bör de tokenbaserade autentiseringsklasserna som är tillgängliga i Azure SDK alltid föredras när du autentiserar till Azure-resurser.

Microsoft rekommenderar att klienter använder antingen Microsoft Entra-ID eller en signatur för delad åtkomst (SAS) för att ge åtkomst till data i Azure Storage. Mer information finns i Auktorisera åtgärder för dataåtkomst.

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 i ACL:n 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 åtkomstkontrollistan (ACL) för en katalog genom att anropa metoden DataLakeDirectoryClient.get_access_control och ange ACL genom att anropa metoden DataLakeDirectoryClient.set_access_control .

Det här exemplet hämtar och anger ACL för en katalog med namnet my-directory. Strängen rwxr-xrw- ger den ägande användaren läs-, skriv- och körningsbehörigheter, ger ägande gruppen endast läs- och körningsbehörigheter och ger alla andra läs- 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. Anropa metoden FileSystemClient._get_root_directory_client för att hämta rotkatalogen.

Ange ACL för en fil

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

Det här exemplet hämtar och anger ACL för en fil med namnet my-file.txt. Strängen rwxr-xrw- ger den ägande användaren läs-, skriv- och körningsbehörigheter, ger ägande gruppen endast läs- och körningsbehörigheter och ger alla andra läs- 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 i ACL:n 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 metoden DataLakeDirectoryClient.set_access_control_recursive .

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 namnet is_default_scope som anger om standard-ACL ska anges. Om parametern är Trueföregås listan över ACL-poster med strängen default:. Posterna i det här exemplet ger följande behörigheter: läsa, skriva och köra behörigheter för den ägande användaren, läsa och köra behörigheter för den ägande gruppen och läsbehörigheter för alla andra. Den senaste ACL-posten i det här exemplet ger en specifik användare med objekt-ID xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx :t läsbehörighet.

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::r-x,other::r--,user:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx:r--'   

        if is_default_scope:
           acl = 'default:user::rwx,default:group::r-x,default:other::r--,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 till ACL utan att påverka andra säkerhetsobjekt som anges i ACL: n. Om du vill ersätta ACL:en i stället för att uppdatera den läser du 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 metoden DataLakeDirectoryClient.update_access_control_recursive . 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 namnet is_default_scope som anger om standard-ACL ska uppdateras. om parametern är Trueföregås den uppdaterade ACL-posten med 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-post som ska tas bort och använder sedan objektet i ta bort ACL-åtgärden. Hämta inte den befintliga ACL:en. Ange bara de ACL-poster som ska tas bort.

Ta bort ACL-poster genom att anropa metoden DataLakeDirectoryClient.remove_access_control_recursive . Om du vill ta bort en ACL-standardpost lägger du till strängen default: 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 namnet is_default_scope som anger om posten ska tas bort från standard-ACL. om parametern är Trueföregås den uppdaterade ACL-posten med 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äkerhetsobjektet 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 med hjälp av 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 använda 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 in värdet None för parametern fortsättningstoken.

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 skickar du inte en fortsättningstoken till metoden DataLakeDirectoryClient.set_access_control_recursive .

Det här exemplet anger ACL-poster rekursivt. Om den här koden påträffar ett behörighetsfel registrerar den det felet och fortsätter körningen. I det här exemplet skrivs antalet fel ut 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.

Metodtips

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

Hantera körningsfel

Ett körningsfel kan inträffa av många orsaker (till exempel ett avbrott eller ett problem med klientanslutningen). Om du stöter på ett körningsfel startar du om den rekursiva ACL-processen. ACL:er kan tillämpas på objekt igen utan att orsaka en negativ inverkan.

Hantera behörighetsfel (403)

Om du stöter på ett undantag för åtkomstkontroll när du kör en rekursiv ACL-process kanske ditt AD-säkerhetsobjekt inte har tillräcklig behörighet för att tillämpa en ACL på ett eller flera av de underordnade objekten i kataloghierarkin. När ett behörighetsfel inträffar stoppas processen och en fortsättningstoken tillhandahålls. Åtgärda behörighetsproblemet och använd sedan fortsättningstoken för att bearbeta den återstående datauppsättningen. Katalogerna och filerna som redan har bearbetats behöver inte bearbetas igen. Du kan också välja att starta om den rekursiva ACL-processen. ACL:er kan tillämpas på objekt igen utan att orsaka en negativ inverkan.

Autentiseringsuppgifter

Vi rekommenderar att du etablerar ett Microsoft Entra-säkerhetsobjekt som har tilldelats rollen Storage Blob Data Owner i omfånget för mållagringskontot eller containern.

Prestanda

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

ACL-gränser

Det maximala antalet ACL:er som du kan använda för 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