Zarządzanie listami ACL w usłudze Azure Data Lake Storage Gen2 przy użyciu języka Python

W tym artykule pokazano, jak używać języka Python do pobierania, ustawiania i aktualizowania list kontroli dostępu katalogów i plików.

Dziedziczenie listy ACL jest już dostępne dla nowych elementów podrzędnych utworzonych w katalogu nadrzędnym. Można jednak również dodawać, aktualizować i usuwać listy ACL cyklicznie w istniejących elementach podrzędnych katalogu nadrzędnego bez konieczności wprowadzania tych zmian indywidualnie dla każdego elementu podrzędnego.

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

Wymagania wstępne

  • Subskrypcja platformy Azure. Aby uzyskać więcej informacji, zobacz Uzyskiwanie bezpłatnej wersji próbnej platformy Azure.

  • Konto magazynu z włączoną hierarchiczną przestrzenią nazw (HNS). Postępuj zgodnie z tymi instrukcjami, aby je utworzyć.

  • Wersja interfejsu wiersza polecenia platformy Azure lub nowsza 2.6.0 .

  • Jedno z następujących uprawnień zabezpieczeń:

    • Aprowizowana jednostka zabezpieczeń identyfikatora entra firmy Microsoft, która została przypisana do roli właściciela danych obiektu blob usługi Storage, w zakresie kontenera docelowego, konta magazynu, nadrzędnej grupy zasobów lub subskrypcji.

    • Właścicielem kontenera docelowego lub katalogu, do którego planujesz zastosować ustawienia listy ACL. Aby ustawić listy ACL cyklicznie, obejmuje to wszystkie elementy podrzędne w kontenerze docelowym lub katalogu.

    • Klucz konta magazynu.

konfigurowanie projektu

Zainstaluj bibliotekę klienta usługi Azure Data Lake Storage dla języka Python przy użyciu narzędzia pip.

pip install azure-storage-file-datalake

Dodaj te instrukcje importu na początku pliku kodu.

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

Połączenie do konta

Aby użyć fragmentów kodu w tym artykule, należy utworzyć wystąpienie Elementu DataLakeServiceClient reprezentujące konto magazynu.

Połączenie przy użyciu identyfikatora Entra firmy Microsoft

Uwaga

Jeśli używasz identyfikatora Entra firmy Microsoft do autoryzowania dostępu, upewnij się, że podmiot zabezpieczeń ma przypisaną rolę Właściciela danych obiektu blob usługi Storage. Aby dowiedzieć się więcej na temat stosowania uprawnień listy ACL i ich skutków, zobacz Model kontroli dostępu w usłudze Azure Data Lake Storage Gen2.

Możesz użyć biblioteki klienta tożsamości platformy Azure dla języka Python do uwierzytelniania aplikacji za pomocą identyfikatora Entra firmy Microsoft.

Najpierw musisz przypisać do podmiotu zabezpieczeń jedną z następujących ról kontroli dostępu na podstawie ról (RBAC) platformy Azure:

Rola Możliwość ustawiania listy ACL
Właściciel danych obiektu blob usługi Storage Wszystkie katalogi i pliki na koncie.
Współautor danych obiektu blob usługi Storage Tylko katalogi i pliki należące do podmiotu zabezpieczeń.

Następnie utwórz wystąpienie Klasy DataLakeServiceClient i przekaż nowe wystąpienie klasy 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

Aby dowiedzieć się więcej na temat używania wartości DefaultAzureCredential do autoryzowania dostępu do danych, zobacz Omówienie: Uwierzytelnianie aplikacji języka Python na platformie Azure przy użyciu zestawu Azure SDK.

Połączenie przy użyciu klucza konta

Dostęp do danych można autoryzować przy użyciu kluczy dostępu do konta (klucza współużytkowanego). W tym przykładzie jest tworzone wystąpienie Elementu DataLakeServiceClient autoryzowane za pomocą klucza konta.

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

Uwaga

Autoryzacja z kluczem udostępnionym nie jest zalecana, ponieważ może być mniej bezpieczna. Aby uzyskać optymalne zabezpieczenia, wyłącz autoryzację za pośrednictwem klucza współdzielonego dla konta magazynu, zgodnie z opisem w temacie Zapobieganie autoryzacji klucza współdzielonego dla konta usługi Azure Storage.

Korzystanie z kluczy dostępu i parametry połączenia powinno być ograniczone do początkowego sprawdzania koncepcji lub prototypów programistycznych, które nie uzyskują dostępu do danych produkcyjnych ani poufnych. W przeciwnym razie klasy uwierzytelniania oparte na tokenach dostępne w zestawie Azure SDK powinny być zawsze preferowane podczas uwierzytelniania w zasobach platformy Azure.

Firma Microsoft zaleca, aby klienci używali identyfikatora Entra firmy Microsoft lub sygnatury dostępu współdzielonego (SAS), aby autoryzować dostęp do danych w usłudze Azure Storage. Aby uzyskać więcej informacji, zobacz Autoryzacja operacji na potrzeby dostępu do danych.

Ustawianie list ACL

Po ustawieniu listy ACL należy zastąpićcałą listę ACL wraz ze wszystkimi jego wpisami. Jeśli chcesz zmienić poziom uprawnień podmiotu zabezpieczeń lub dodać nowego podmiotu zabezpieczeń do listy ACL bez wpływu na inne istniejące wpisy, należy zaktualizować listę ACL. Aby zaktualizować listę ACL zamiast jej zastąpić, zobacz sekcję Aktualizowanie list ACL w tym artykule.

W tej sekcji pokazano, jak wykonać następujące działania:

  • Ustawianie listy ACL katalogu
  • Ustawianie listy ACL pliku

Ustawianie listy ACL katalogu

Pobierz listę kontroli dostępu (ACL) katalogu, wywołując metodę DataLakeDirectoryClient.get_access_control i ustawiając listę ACL, wywołując metodę DataLakeDirectoryClient.set_access_control.

Ten przykład pobiera i ustawia listę ACL katalogu o nazwie my-directory. Ciąg rwxr-xrw- daje właścicielowi uprawnienia do odczytu, zapisu i wykonywania użytkownika, nadaje grupie właściciel tylko uprawnienia do odczytu i wykonywania oraz nadaje wszystkim innym uprawnienie do odczytu i zapisu.

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)

Listę ACL katalogu głównego kontenera można również pobrać i ustawić. Aby uzyskać katalog główny, wywołaj metodę FileSystemClient._get_root_directory_client .

Ustawianie listy ACL pliku

Pobierz listę kontroli dostępu (ACL) pliku, wywołując metodę DataLakeFileClient.get_access_control i ustawiając listę ACL przez wywołanie metody DataLakeFileClient.set_access_control.

Ten przykład pobiera i ustawia listę ACL pliku o nazwie my-file.txt. Ciąg rwxr-xrw- daje właścicielowi uprawnienia do odczytu, zapisu i wykonywania użytkownika, nadaje grupie właściciel tylko uprawnienia do odczytu i wykonywania oraz nadaje wszystkim innym uprawnienie do odczytu i zapisu.

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)

Cykliczne ustawianie list kontroli dostępu

Po ustawieniu listy ACL należy zastąpićcałą listę ACL wraz ze wszystkimi jego wpisami. Jeśli chcesz zmienić poziom uprawnień podmiotu zabezpieczeń lub dodać nowego podmiotu zabezpieczeń do listy ACL bez wpływu na inne istniejące wpisy, należy zaktualizować listę ACL. Aby zaktualizować listę ACL zamiast jej zastąpić, zobacz cyklicznie sekcję Update ACL tego artykułu.

Ustaw listy ACL rekursywnie, wywołując metodę DataLakeDirectoryClient.set_access_control_recursive .

Jeśli chcesz ustawić domyślny wpis listy ACL, dodaj ciąg na początku każdego ciągu default: wpisu listy ACL.

W tym przykładzie ustawiono listę ACL katalogu o nazwie my-parent-directory.

Ta metoda akceptuje parametr logiczny o nazwie is_default_scope , który określa, czy ustawić domyślną listę ACL. Jeśli ten parametr to True, lista wpisów listy ACL jest poprzedzona ciągiem default:. Wpisy w tym przykładzie zapewniają następujące uprawnienia: uprawnienia do odczytu, zapisu i wykonywania dla użytkownika, który jest właścicielem, odczyt i wykonywanie uprawnień dla grupy właścicieli oraz uprawnienia do odczytu dla wszystkich innych. Ostatni wpis listy ACL w tym przykładzie daje określonego użytkownika z uprawnieniami do odczytu identyfikatora xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx obiektu.

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)

Aby zobaczyć przykład, który przetwarza listy ACL cyklicznie w partiach, określając rozmiar partii, zobacz przykład języka Python.

Rekursywne aktualizowanie list ACL

Podczas aktualizowania listy ACL należy zmodyfikować listę ACL zamiast zastąpić listę ACL. Można na przykład dodać nowego podmiotu zabezpieczeń do listy ACL bez wpływu na inne podmioty zabezpieczeń wymienione na liście ACL. Aby zastąpić listę ACL zamiast ją zaktualizować, zobacz sekcję Ustawianie list ACL w tym artykule.

Aby zaktualizować listę ACL rekursywnie, utwórz nowy obiekt listy ACL z wpisem listy ACL, który chcesz zaktualizować, a następnie użyj tego obiektu w operacji aktualizacji listy ACL. Nie pobieraj istniejącej listy ACL, po prostu podaj wpisy listy ACL do zaktualizowania. Zaktualizuj listę ACL rekursywnie, wywołując metodę DataLakeDirectoryClient.update_access_control_recursive . Jeśli chcesz zaktualizować domyślny wpis listy ACL, dodaj ciąg na początku każdego ciągu default: wpisu listy ACL.

W tym przykładzie zaktualizowano wpis listy ACL z uprawnieniami do zapisu.

W tym przykładzie ustawiono listę ACL katalogu o nazwie my-parent-directory. Ta metoda akceptuje parametr logiczny o nazwie is_default_scope , który określa, czy zaktualizować domyślną listę ACL. jeśli ten parametr to True, zaktualizowany wpis listy ACL jest poprzedzony ciągiem 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)

Aby zobaczyć przykład, który przetwarza listy ACL cyklicznie w partiach, określając rozmiar partii, zobacz przykład języka Python.

Usuwanie wpisów listy ACL rekursywnie

Można usunąć co najmniej jeden wpis listy ACL. Aby usunąć wpisy listy ACL cyklicznie, utwórz nowy obiekt listy ACL dla wpisu listy ACL do usunięcia, a następnie użyj tego obiektu w operacji usuwania listy ACL. Nie pobieraj istniejącej listy ACL, po prostu podaj wpisy listy ACL do usunięcia.

Usuń wpisy listy ACL, wywołując metodę DataLakeDirectoryClient.remove_access_control_recursive . Jeśli chcesz usunąć domyślny wpis listy ACL, dodaj ciąg default: na początku ciągu wpisu listy ACL.

W tym przykładzie usunięto wpis listy ACL z listy ACL katalogu o nazwie my-parent-directory. Ta metoda akceptuje parametr logiczny o nazwie is_default_scope , który określa, czy usunąć wpis z domyślnej listy ACL. jeśli ten parametr to True, zaktualizowany wpis listy ACL jest poprzedzony ciągiem 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)

Aby zobaczyć przykład, który przetwarza listy ACL cyklicznie w partiach, określając rozmiar partii, zobacz przykład języka Python.

Odzyskiwanie po awariach

Mogą wystąpić błędy środowiska uruchomieniowego lub uprawnień. W przypadku błędów środowiska uruchomieniowego uruchom ponownie proces od początku. Błędy uprawnień mogą wystąpić, jeśli podmiot zabezpieczeń nie ma wystarczających uprawnień do modyfikowania listy ACL katalogu lub pliku, który znajduje się w hierarchii katalogów, które są modyfikowane. Rozwiąż problem z uprawnieniami, a następnie wybierz, aby wznowić proces od punktu awarii przy użyciu tokenu kontynuacji lub uruchomić ponownie proces od początku. Jeśli wolisz ponownie uruchomić od początku, nie musisz używać tokenu kontynuacji. Możesz ponownie zastosować wpisy listy ACL bez negatywnego wpływu.

Ten przykład zwraca token kontynuacji w przypadku awarii. Aplikacja może wywołać tę przykładową metodę ponownie po usunięciu błędu i przekazać token kontynuacji. Jeśli ta przykładowa metoda jest wywoływana po raz pierwszy, aplikacja może przekazać wartość None parametru tokenu kontynuacji.

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

Aby zobaczyć przykład, który przetwarza listy ACL cyklicznie w partiach, określając rozmiar partii, zobacz przykład języka Python.

Jeśli chcesz, aby proces był nieprzerwany przez błędy uprawnień, możesz to określić.

Aby upewnić się, że proces zakończy się nieprzerwanie, nie przekazuj tokenu kontynuacji do metody DataLakeDirectoryClient.set_access_control_recursive .

W tym przykładzie cyklicznie ustawiane są wpisy listy ACL. Jeśli ten kod napotka błąd uprawnień, rejestruje ten błąd i kontynuuje wykonywanie. W tym przykładzie jest drukowana liczba niepowodzeń w konsoli programu .

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)

Aby zobaczyć przykład, który przetwarza listy ACL cyklicznie w partiach, określając rozmiar partii, zobacz przykład języka Python.

Najlepsze rozwiązania

Ta sekcja zawiera wskazówki dotyczące najlepszych rozwiązań dotyczących cyklicznego ustawiania list ACL.

Obsługa błędów środowiska uruchomieniowego

Błąd środowiska uruchomieniowego może wystąpić z wielu powodów (na przykład: awaria lub problem z łącznością klienta). Jeśli wystąpi błąd środowiska uruchomieniowego, uruchom ponownie cyklicznego procesu listy ACL. Listy ACL można ponownie zastosować do elementów bez negatywnego wpływu.

Obsługa błędów uprawnień (403)

Jeśli wystąpi wyjątek kontroli dostępu podczas uruchamiania cyklicznego procesu listy ACL, podmiot zabezpieczeń usługi AD może nie mieć wystarczających uprawnień do zastosowania listy ACL do co najmniej jednego elementu podrzędnego w hierarchii katalogów. Po wystąpieniu błędu uprawnień proces zostanie zatrzymany i zostanie udostępniony token kontynuacji. Rozwiąż problem z uprawnieniami, a następnie użyj tokenu kontynuacji, aby przetworzyć pozostały zestaw danych. Katalogi i pliki, które zostały już pomyślnie przetworzone, nie będą musiały zostać ponownie przetworzone. Możesz również ponownie uruchomić cyklicznego procesu listy ACL. Listy ACL można ponownie zastosować do elementów bez negatywnego wpływu.

Poświadczenia

Zalecamy aprowizację podmiotu zabezpieczeń firmy Microsoft, któremu przypisano rolę Właściciela danych obiektu blob usługi Storage w zakresie docelowego konta magazynu lub kontenera.

Wydajność

Aby zmniejszyć opóźnienie, zalecamy uruchomienie cyklicznego procesu listy ACL na maszynie wirtualnej platformy Azure znajdującej się w tym samym regionie co konto magazynu.

Limity listy ACL

Maksymalna liczba list ACL, które można zastosować do katalogu lub pliku, to 32 listy ACL dostępu i 32 domyślne listy ACL. Aby uzyskać więcej informacji, zobacz Kontrola dostępu w usłudze Azure Data Lake Storage Gen2.

Zobacz też