Использование .NET для управления списками управления доступом в Azure Data Lake Storage
В этой статье показано, как использовать .NET для получения, настройки и обновления списков управления доступом к каталогам и файлам.
Наследование ACL уже доступно для новых дочерних элементов, созданных в родительском каталоге. Но можно также добавлять, обновлять и удалять списки управления доступом для существующих дочерних элементов родительского каталога без необходимости вносить эти изменения отдельно для каждого дочернего элемента.
Пакет (NuGet) | Примеры | Справочник по API | Сопоставление Gen1 с Gen2 | Отправить отзыв
- Подписка Azure — создайте бесплатную учетную запись.
- Учетная запись хранения Azure с включенным иерархическим пространством имен (HNS). Выполните эти инструкции, чтобы создать учетную запись.
- Azure CLI версии
2.6.0
или выше. - Одно из следующих разрешений безопасности:
- Подготовленный субъект безопасности Идентификатора Microsoft Entra, которому назначена роль владельца данных BLOB-объектов хранилища, в пределах целевого контейнера, учетной записи хранения, родительской группы ресурсов или подписки.
- Пользователь-владелец целевого контейнера или каталога, к которому планируется применять параметры ACL. Следует настроить ACL рекурсивно, то есть для всех дочерних элементов в целевом контейнере или каталоге.
- Ключ учетной записи хранения.
В этом разделе показано, как настроить проект для работы с клиентской библиотекой служба хранилища Azure Data Lake.
В каталоге проекта установите пакеты для клиентских библиотек служба хранилища Azure Data Lake и Azure Identity с помощью dotnet add package
команды. Пакет Azure.Identity необходим для бессерверных подключений к службам Azure.
dotnet add package Azure.Storage.Files.DataLake
dotnet add package Azure.Identity
Добавьте эти using
директивы в начало файла кода:
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;
Чтобы запустить примеры кода в этой статье, необходимо создать экземпляр DataLakeServiceClient , представляющий учетную запись хранения. Вы можете авторизовать клиентский объект с помощью учетных данных идентификатора Microsoft Entra или с помощью ключа учетной записи.
Клиентская библиотека удостоверений Azure для .NET можно использовать для проверки подлинности приложения с помощью идентификатора Microsoft Entra.
Примечание
Если вы используете идентификатор Microsoft Entra для авторизации доступа, убедитесь, что субъект безопасности назначен роль владельца данных BLOB-объектов хранилища. Дополнительные сведения о применении разрешений ACL и последствиях их изменения см. в статье "Модель управления доступом" в Azure Data Lake Storage.
Сначала назначьте одной из следующих ролей Azure управление доступом на основе ролей (Azure RBAC) субъекту безопасности:
Роль | Возможности настройки ACL |
---|---|
владелец данных BLOB-объектов хранилища; | Все каталоги и файлы в учетной записи. |
Участник данных хранилища BLOB-объектов | Только каталоги и файлы, которыми владеет субъект безопасности. |
Затем создайте экземпляр DataLakeServiceClient и передайте новый экземпляр класса 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;
}
Дополнительные сведения об использовании DefaultAzureCredential для авторизации доступа к данным см. в статье "Проверка подлинности приложений .NET с помощью служб Azure".
При установке ACL вы замените весь список ACL, включая все его записи. Если вы хотите изменить уровень разрешений субъекта безопасности или добавить новый субъект безопасности в список управления доступом, не затрагивая другие существующие записи, следует обновить ACL. Сведения о том, как обновить список управления доступом вместо его замены, см. в разделе Обновление списков ACL этой статьи.
Если вы решили настроить ACL, необходимо добавить запись для пользователя-владельца, запись для группы-владельца и запись для всех других пользователей. Дополнительные сведения о пользователе-владельце, группе-владельце и других пользователях см. в разделе Пользователи и удостоверения.
В этом разделе показано, как выполнять следующие действия.
- Настройка ACL для каталога
- Настройка ACL для файла
- Рекурсивная настройка ACL
Получите список управления доступом (ACL) каталога, вызвав метод DataLakeDirectoryClient.GetAccessControlAsync, и настройте ACL, вызвав метод DataLakeDirectoryClient.SetAccessControlList .
В этом примере мы получаем список ACL и настраиваем его для каталога с именем my-directory
. В строке user::rwx,group::r-x,other::rw-
пользователю-владельцу предоставляются разрешения на чтение, запись и выполнение, группе-владельцу — только на чтение и выполнение, а всем остальным — только на чтение и запись.
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);
}
Вы также можете получить и настроить ACL для корневого каталога контейнера. Чтобы получить корневой каталог, передайте пустую строку (""
) в метод DataLakeFileSystemClient.GetDirectoryClient.
Получите список управления доступом (ACL) файла, вызвав метод DataLakeFileClient.GetAccessControlAsync, и настройте ACL, вызвав метод DataLakeFileClient.SetAccessControlList .
В этом примере мы получаем список ACL и настраиваем его для файла с именем my-file.txt
. В строке user::rwx,group::r-x,other::rw-
пользователю-владельцу предоставляются разрешения на чтение, запись и выполнение, группе-владельцу — только на чтение и выполнение, а всем остальным — только на чтение и запись.
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);
}
Чтобы настроить списки ACL рекурсивно, вызовите метод DataLakeDirectoryClient.SetAccessControlRecursiveAsync. Передайте в этот метод Список PathAccessControlItem. Каждый объект PathAccessControlItem определяет запись ACL.
Если нужно настроить запись ACL по умолчанию, можно установить для свойства PathAccessControlItem.DefaultScope в PathAccessControlItem значение true.
В этом примере список ACL задается для каталога my-parent-directory
. Этот метод принимает логический параметр с именем isDefaultScope
, указывающий, следует ли задавать ACL по умолчанию. Этот параметр используется в конструкторе PathAccessControlItem. Эти записи ACL предоставляют пользователю-владельцу разрешения на чтение, запись и выполнение, группе-владельцу — только на чтение и выполнение, а всем остальным доступ не предоставляется. Последняя запись ACL в этом примере предоставляет определенному пользователю разрешение на чтение и выполнение идентификатора xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
объекта.
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);
}
При обновлении ACL происходит его изменение, а не полная замена. Например, можно добавить новый субъект безопасности в ACL, не затрагивая другие субъекты безопасности, перечисленные в этом же списке. Сведения о том, как заменить ACL вместо его обновления, см. в разделе Задание ACL этой статьи.
В этом разделе показано, как выполнять следующие действия.
- Обновление списка ACL
- Рекурсивное обновление ACL
Сначала получите список ACL для каталога, вызвав метод DataLakeDirectoryClient.GetAccessControlAsync. Скопируйте список записей ACL в новый список объектов PathAccessControl. Затем найдите запись, которую требуется обновить, и замените ее в списке. Задайте список ACL, вызвав метод DataLakeDirectoryClient.SetAccessControlList.
В этом примере корневой ACL контейнера обновляется путем замены записи ACL для всех остальных пользователей.
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);
}
}
Чтобы обновить ACL рекурсивно, создайте новый объект ACL с записью, которую требуется обновить, а затем используйте его в операции обновления ACL. Не получите существующий список ACL, просто предоставьте обновляемые записи ACL.
Для рекурсивного обновления ACL нужно вызвать метод DataLakeDirectoryClient.UpdateAccessControlRecursiveAsync. Передайте в этот метод Список PathAccessControlItem. Каждый объект PathAccessControlItem определяет запись ACL.
Если нужно обновить запись ACL по умолчанию, можно установить для свойства PathAccessControlItem.DefaultScope в PathAccessControlItem значение true.
В этом примере обновляется запись ACL с разрешением на запись. Этот метод принимает логический параметр с именем isDefaultScope
, указывающий, следует ли обновлять ACL по умолчанию. Этот параметр используется в конструкторе 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);
}
Вы можете удалить одну или несколько записей ACL. В этом разделе показано, как выполнять следующие действия.
- Удаление записи ACL
- Рекурсивное удаление записей ACL
Сначала получите список ACL для каталога, вызвав метод DataLakeDirectoryClient.GetAccessControlAsync. Скопируйте список записей ACL в новый список объектов PathAccessControl. Затем найдите запись, которую нужно удалить, и вызовите метод Remove коллекции. Задайте обновленный список ACL, вызвав метод DataLakeDirectoryClient.SetAccessControlList.
В этом примере корневой ACL контейнера обновляется путем замены записи ACL для всех остальных пользователей.
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);
}
}
Чтобы удалить записи ACL рекурсивно, создайте новый объект ACL для удаляемой записи, а затем используйте его в операции удаления ACL. Не получите существующий список ACL, просто укажите записи ACL для удаления.
Удалите записи ACL, вызвав метод DataLakeDirectoryClient.RemoveAccessControlRecursiveAsync. Передайте в этот метод Список PathAccessControlItem. Каждый объект PathAccessControlItem определяет запись ACL.
Если нужно удалить запись ACL по умолчанию, можно установить для свойства PathAccessControlItem.DefaultScope в PathAccessControlItem значение true.
В этом примере удаляется запись ACL из списка управления доступом для каталога my-parent-directory
. Этот метод принимает логический параметр с именем isDefaultScope
, указывающий, следует ли удалять запись из ACL по умолчанию. Этот параметр используется в конструкторе 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);
}
При рекурсивном изменении ACL могут возникать ошибки времени выполнения или разрешений. При ошибках времени выполнения перезапустите процесс с самого начала. Ошибки разрешений могут возникать, если субъект безопасности не имеет достаточных разрешений для изменения ACL каталога или файла в изменяемой иерархии каталогов. Устраните проблему с разрешениями, а затем возобновите процесс с точки сбоя с помощью маркера продолжения или перезапустите его с самого начала. Во втором случае использовать маркер продолжения не нужно. Вы можете повторно применить ACL без отрицательных последствий.
В этом примере в случае сбоя возвращается маркер продолжения. Приложение может снова вызвать этот метод после устранения ошибки и передать маркер продолжения. Если этот метод вызывается впервые, приложение может передать в него значение null
для параметра маркера продолжения.
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;
}
}
Если вы хотите, чтобы процесс продолжался без прерывания на ошибки разрешений, можно указать это.
Чтобы убедиться в том, что процесс завершается без прерывания, передайте объект AccessControlChangedOptions и задайте для свойства ContinueOnFailure этого объекта значение true
.
В этом примере записи ACL задаются рекурсивно. Если этот код вызывает ошибку разрешения, он регистрирует этот сбой и возобновляет выполнение. В этом примере на консоль выводится число сбоев.
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());
}
В этом разделе приведены рекомендации по рекурсивной настройке списков управления доступом.
Ошибки времени выполнения могут возникать по многим причинам (например, в случае сбоя или проблемы с подключением клиента). При возникновении ошибки времени выполнения перезапустите процесс рекурсивной настройки ACL. Списки управления доступом можно повторно применить к элементам без негативного воздействия.
Если при выполнении процесса рекурсивной настройки ACL возникает исключение управления доступом, возможно, что субъект безопасности Active Directory не имеет достаточных разрешений для применения ACL к одному или нескольким дочерним элементам в иерархии каталогов. При возникновении ошибки, связанной с разрешением, процесс останавливается и предоставляется маркер продолжения. Устраните проблему с разрешениями, а затем используйте маркер продолжения для обработки оставшегося набора данных. Каталоги и файлы, которые уже были успешно обработаны, не должны обрабатываться повторно. Можно также перезапустить процесс рекурсивной настройки ACL. Списки управления доступом можно повторно применить к элементам без негативного воздействия.
Рекомендуется подготовить субъект безопасности Microsoft Entra, которому назначена роль владельца данных BLOB-объектов хранилища в области целевой учетной записи хранения или контейнера.
Чтобы сократить задержку, рекомендуется запустить процесс рекурсивной настройки ACL на виртуальной машине Azure, расположенной в том же регионе, что и учетная запись хранения.
Максимальное число списков управления доступом, которое можно применить к каталогу или файлу, составляет 32 списка для доступа и 32 списка по умолчанию. Дополнительные сведения см. в статье Контроль доступа в Azure Data Lake Storage 2-го поколения.