Поделиться через


Использование Python для управления списками управления доступом в Azure Data Lake Storage

В этой статье показано, как использовать Python для получения, настройки и обновления списков управления доступом к каталогам и файлам.

Наследование ACL уже доступно для новых дочерних элементов, созданных в родительском каталоге. Но можно также добавлять, обновлять и удалять списки управления доступом для существующих дочерних элементов родительского каталога без необходимости вносить эти изменения отдельно для каждого дочернего элемента.

Пакет (индекс пакета Python) | Примеры | Рекурсивные примеры ACL | Справочник по API | Сопоставление 1-го поколения со 2-м | Отправить отзыв

Необходимые компоненты

  • Подписка Azure — создайте бесплатную учетную запись.
  • Учетная запись хранения Azure с включенным иерархическим пространством имен (HNS). Выполните эти инструкции, чтобы создать учетную запись.
  • Python 3.8+
  • Azure CLI версии2.6.0 или выше.
  • Одно из следующих разрешений безопасности:
    • Подготовленный субъект безопасности Идентификатора Microsoft Entra, которому назначена роль владельца данных BLOB-объектов хранилища, в пределах целевого контейнера, учетной записи хранения, родительской группы ресурсов или подписки.
    • Пользователь-владелец целевого контейнера или каталога, к которому планируется применять параметры ACL. Следует настроить ACL рекурсивно, то есть для всех дочерних элементов в целевом контейнере или каталоге.
    • Ключ учетной записи хранения.

Настройка проекта

В этом разделе описывается подготовка проекта для работы с клиентской библиотекой Azure Data Lake Storage для Python.

В каталоге проекта установите пакеты для клиентских библиотек Azure Data Lake Storage и Azure Identity с помощью pip install команды. Пакет azure-identity необходим для бессерверных подключений к службам Azure.

pip install azure-storage-file-datalake azure-identity

Затем откройте файл кода и добавьте необходимые инструкции импорта. В этом примере мы добавим следующее в файл .py :

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

Подключение к учетной записи

Чтобы запустить примеры кода в этой статье, необходимо создать экземпляр DataLakeServiceClient , представляющий учетную запись хранения. Вы можете авторизовать клиентский объект с помощью учетных данных идентификатора Microsoft Entra или с помощью ключа учетной записи.

Клиентская библиотека удостоверений Azure для Python используется для проверки подлинности приложения с помощью идентификатора Microsoft Entra.

Примечание.

Если вы используете идентификатор Microsoft Entra для авторизации доступа, убедитесь, что субъект безопасности назначен роль владельца данных BLOB-объектов хранилища. Дополнительные сведения о применении разрешений ACL и последствиях их изменения см. в статье "Модель управления доступом" в Azure Data Lake Storage.

Сначала назначьте одной из следующих ролей Azure управление доступом на основе ролей (Azure RBAC) субъекту безопасности:

Роль Возможности настройки ACL
владелец данных BLOB-объектов хранилища; Все каталоги и файлы в учетной записи.
Участник данных хранилища BLOB-объектов Только каталоги и файлы, которыми владеет субъект безопасности.

Затем создайте экземпляр DataLakeServiceClient и передайте новый экземпляр класса 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

Дополнительные сведения об использовании DefaultAzureCredential для авторизации доступа к данным см. в статье "Обзор: проверка подлинности приложений Python в Azure с помощью пакета SDK Azure".

Настройка списков ACL

При установке ACL вы замените весь список ACL, включая все его записи. Если вы хотите изменить уровень разрешений субъекта безопасности или добавить новый субъект безопасности в список управления доступом, не затрагивая другие существующие записи, следует обновить ACL. Сведения о том, как обновить список управления доступом вместо его замены, см. в разделе Обновление списков ACL этой статьи.

В этом разделе показано, как выполнять следующие действия.

  • Настройка ACL для каталога
  • Настройка ACL для файла

Настройка ACL для каталога

Получите список управления доступом (ACL) каталога, вызвав метод DataLakeDirectoryClient.get_access_control, и настройте ACL, вызвав метод DataLakeDirectoryClient.set_access_control.

В этом примере мы получаем список ACL и настраиваем его для каталога с именем my-directory. В строке rwxr-xrw- пользователю-владельцу предоставляются разрешения на чтение, запись и выполнение, группе-владельцу — только на чтение и выполнение, а всем остальным — только на чтение и запись.

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)

Вы также можете получить и настроить ACL для корневого каталога контейнера. Чтобы получить корневой каталог, вызовите метод FileSystemClient._get_root_directory_client.

Настройка ACL для файла

Получите список управления доступом (ACL) файла, вызвав метод DataLakeFileClient.get_access_control, и настройте ACL, вызвав метод DataLakeFileClient.set_access_control.

В этом примере мы получаем список ACL и настраиваем его для файла с именем my-file.txt. В строке rwxr-xrw- пользователю-владельцу предоставляются разрешения на чтение, запись и выполнение, группе-владельцу — только на чтение и выполнение, а всем остальным — только на чтение и запись.

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)

Рекурсивная настройка ACL

При установке ACL вы замените весь список ACL, включая все его записи. Если вы хотите изменить уровень разрешений субъекта безопасности или добавить новый субъект безопасности в список управления доступом, не затрагивая другие существующие записи, следует обновить ACL. Сведения о том, как обновить список управления доступом вместо его замены, см. в разделе Рекурсивное обновление списков ACL этой статьи.

Чтобы настроить списки ACL рекурсивно, вызовите метод DataLakeDirectoryClient.set_access_control_recursive.

Если вы хотите задать запись ACL по умолчанию, добавьте строку default: в начало каждой строки записи ACL.

В этом примере список ACL задается для каталога my-parent-directory.

Этот метод принимает логический параметр с именем is_default_scope, указывающий, следует ли задавать ACL по умолчанию. Если этот параметр имеет значение True, перед строкой default:предшествует список записей ACL. Записи в этом примере предоставляют следующие разрешения: чтение, запись и выполнение разрешений для пользователя, чтения и выполнения разрешений для группы владельцев, а также разрешений на чтение для всех остальных. Последняя запись ACL в этом примере предоставляет определенному пользователю разрешения на чтение идентификатора xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx объекта.

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)

Пример рекурсивной пакетной обработки списков управления доступом, для которой вам нужно указать размер пакета, см. в примере Python.

Рекурсивное обновление ACL

При обновлении ACL происходит его изменение, а не полная замена. Например, можно добавить новый субъект безопасности в ACL, не затрагивая другие субъекты безопасности, перечисленные в этом же списке. Сведения о том, как заменить ACL вместо его обновления, см. в разделе Задание ACL этой статьи.

Чтобы обновить ACL рекурсивно, создайте новый объект ACL с записью, которую требуется обновить, а затем используйте его в операции обновления ACL. Не изменяйте существующий список ACL, просто предоставьте записи ACL, которые необходимо обновить. Для рекурсивного обновления ACL нужно вызвать метод DataLakeDirectoryClient.update_access_control_recursive. Если вы хотите обновить запись ACL по умолчанию, добавьте строку default: в начало каждой строки записи ACL.

В этом примере обновляется запись ACL с разрешением на запись.

В этом примере список ACL задается для каталога my-parent-directory. Этот метод принимает логический параметр с именем is_default_scope, указывающий, следует ли обновлять ACL по умолчанию. Если этот параметр имеет значение True, обновленной записи ACL предшествует строка 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)

Пример рекурсивной пакетной обработки списков управления доступом, для которой вам нужно указать размер пакета, см. в примере Python.

Рекурсивное удаление записей ACL

Вы можете удалить одну или несколько записей ACL. Чтобы удалить записи ACL рекурсивно, создайте новый объект ACL для удаляемой записи, а затем используйте его в операции удаления ACL. Не изменяйте существующий список ACL, просто предоставьте записи ACL, которые необходимо удалить.

Удалите записи ACL, вызвав метод DataLakeDirectoryClient.remove_access_control_recursive. Если вы хотите удалить запись ACL по умолчанию, добавьте строку default: в начало строки записи ACL.

В этом примере удаляется запись ACL из списка управления доступом для каталога my-parent-directory. Этот метод принимает логический параметр с именем is_default_scope, указывающий, следует ли удалять запись из ACL по умолчанию. Если этот параметр имеет значение True, перед строкой default:предшествует обновленная запись ACL.

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)

Пример рекурсивной пакетной обработки списков управления доступом, для которой вам нужно указать размер пакета, см. в примере Python.

Восстановление после сбоев

Вы можете столкнуться с ошибками, связанными с выполнением или с разрешениями. При ошибках времени выполнения перезапустите процесс с самого начала. Ошибки разрешений могут возникать, если субъект безопасности не имеет достаточных разрешений для изменения ACL каталога или файла в изменяемой иерархии каталогов. Устраните проблему с разрешениями, а затем возобновите процесс с точки сбоя с помощью маркера продолжения или перезапустите его с самого начала. Во втором случае использовать маркер продолжения не нужно. Вы можете повторно применить ACL без отрицательных последствий.

В этом примере в случае сбоя возвращается маркер продолжения. Приложение может снова вызвать этот метод после устранения ошибки и передать маркер продолжения. Если этот метод вызывается впервые, приложение может передать в него значение None для параметра маркера продолжения.

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

Пример рекурсивной пакетной обработки списков управления доступом, для которой вам нужно указать размер пакета, см. в примере Python.

Если вы хотите, чтобы процесс продолжался без прерывания на ошибки разрешений, можно указать это.

Чтобы гарантировать, что процесс завершается без прерывания, не передавайте маркер продолжения в метод DataLakeDirectoryClient.set_access_control_recursive.

В этом примере записи ACL задаются рекурсивно. Если этот код вызывает ошибку разрешения, он регистрирует этот сбой и возобновляет выполнение. В этом примере на консоль выводится число сбоев.

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)

Пример рекурсивной пакетной обработки списков управления доступом, для которой вам нужно указать размер пакета, см. в примере Python.

Рекомендации

В этом разделе приведены рекомендации по рекурсивной настройке списков управления доступом.

Обработка ошибок времени выполнения

Ошибки времени выполнения могут возникать по многим причинам (например, в случае сбоя или проблемы с подключением клиента). При возникновении ошибки времени выполнения перезапустите процесс рекурсивной настройки ACL. Списки управления доступом можно повторно применить к элементам без негативного воздействия.

Обработка ошибок разрешений (403)

Если при выполнении процесса рекурсивной настройки ACL возникает исключение управления доступом, возможно, что субъект безопасности Active Directory не имеет достаточных разрешений для применения ACL к одному или нескольким дочерним элементам в иерархии каталогов. При возникновении ошибки, связанной с разрешением, процесс останавливается и предоставляется маркер продолжения. Устраните проблему с разрешениями, а затем используйте маркер продолжения для обработки оставшегося набора данных. Каталоги и файлы, которые уже были успешно обработаны, не должны обрабатываться повторно. Можно также перезапустить процесс рекурсивной настройки ACL. Списки управления доступом можно повторно применить к элементам без негативного воздействия.

Подтверждение компетенции

Рекомендуется подготовить субъект безопасности Microsoft Entra, которому назначена роль владельца данных BLOB-объектов хранилища в области целевой учетной записи хранения или контейнера.

Производительность

Чтобы сократить задержку, рекомендуется запустить процесс рекурсивной настройки ACL на виртуальной машине Azure, расположенной в том же регионе, что и учетная запись хранения.

Ограничения для списков управления доступом

Максимальное число списков управления доступом, которое можно применить к каталогу или файлу, составляет 32 списка для доступа и 32 списка по умолчанию. Дополнительные сведения см. в статье Контроль доступа в Azure Data Lake Storage 2-го поколения.

См. также