Bagikan melalui


Gunakan .NET untuk mengelola ACL di Azure Data Lake Storage

Artikel ini memperlihatkan kepada Anda cara menggunakan .NET untuk mendapatkan, mengatur, dan memperbarui daftar kontrol akses direktori dan file.

Pewarisan ACL sudah tersedia untuk item anak baru yang dibuat dalam direktori induk. Namun Anda juga dapat menambahkan, memperbarui, dan menghapus ACL secara berulang pada item anak yang ada dari direktori induk tanpa harus melakukan perubahan ini satu per satu untuk setiap item anak.

Paket (NuGet) | Sampel | Referensi | APIPemetaan | Berikan Umpan Balik

Prerequisites

  • Langganan Azure - membuat langganan secara gratis.
  • Akun penyimpanan Azure yang mengaktifkan namespace hierarkis (HNS). Ikuti petunjuk berikut untuk membuatnya.
  • Azure CLI versi 2.6.0 atau lebih tinggi.
  • Salah satu izin keamanan berikut:
    • Principal keamanan Microsoft Entra ID yang disediakan yang telah ditetapkan sebagai Pemilik Data Blob Penyimpanan, diberikan lingkup pada kontainer target, akun penyimpanan, grup sumber daya induk, atau langganan.
    • Pengguna pemilik kontainer target atau direktori tempat Anda berencana menerapkan pengaturan ACL. Untuk mengatur ACL secara berulang, ini mencakup semua item anak dalam kontainer atau direktori target.
    • Kunci akun penyimpanan.

Menyiapkan proyek Anda

Bagian ini memperlihatkan kepada Anda cara menyiapkan proyek untuk bekerja dengan pustaka klien Azure Storage Data Lake.

Memasang paket

Dari direktori proyek Anda, instal paket untuk pustaka klien Azure Storage Data Lake dan Azure Identity menggunakan dotnet add package perintah . Paket Azure.Identity diperlukan untuk koneksi tanpa kata sandi ke layanan Azure.

dotnet add package Azure.Storage.Files.DataLake
dotnet add package Azure.Identity

Tambahkan using direktif

Tambahkan arahan ini using ke bagian atas file kode Anda:

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;

Sambungkan ke akun

Untuk menjalankan contoh kode dalam artikel ini, Anda perlu membuat instans DataLakeServiceClient yang mewakili akun penyimpanan. Anda dapat mengotorisasi objek klien dengan kredensial ID Microsoft Entra atau dengan kunci akun.

Anda dapat menggunakan pustaka klien identitas Azure untuk .NET untuk mengautentikasi aplikasi Anda dengan ID Microsoft Entra.

Note

Jika Anda menggunakan ID Microsoft Entra untuk mengotorisasi akses, pastikan bahwa prinsipal keamanan Anda telah diberi peran Pemilik Data Blob Penyimpanan. Untuk mempelajari selengkapnya tentang bagaimana izin ACL diterapkan dan efek mengubahnya, lihat Model kontrol akses di Azure Data Lake Storage.

Pertama, tetapkan salah satu peran kontrol akses berbasis peran Azure (Azure RBAC) berikut ini ke prinsip keamanan Anda:

Role Kapabilitas pengaturan ACL
Pemilik Data Blob Penyimpanan Semua direktori dan file dalam akun tersebut.
Kontributor Data untuk Blob Penyimpanan Hanya direktori dan file yang dimiliki oleh prinsipal keamanan.

Selanjutnya, buat instans DataLakeServiceClient dan berikan instans baru dari kelas 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;
}

Untuk mempelajari selengkapnya tentang menggunakan DefaultAzureCredential untuk mengotorisasi akses ke data, lihat Cara mengautentikasi aplikasi .NET dengan layanan Azure.

Tetapkan ACL

Saat Anda mengatur ACL, Anda mengganti seluruh ACL termasuk semua entrinya. Jika Anda ingin mengubah tingkat izin prinsipal keamanan atau menambahkan prinsipal keamanan baru ke ACL tanpa memengaruhi entri lain yang sudah ada, Anda harus memperbarui ACL sebagai gantinya. Untuk memperbarui ACL alih-alih menggantinya, lihat bagian Memperbarui ACL dari artikel ini.

Jika Anda memilih untuk mengatur ACL, Anda harus menambahkan entri untuk pengguna pemilik, entri untuk grup pemilik, dan entri untuk semua pengguna lain. Untuk mempelajari selengkapnya tentang pengguna pemilik, grup pemilik, dan semua pengguna lainnya, lihat Pengguna dan identitas.

Bagian ini memperlihatkan kepada Anda cara:

  • Atur pengaturan ACL dari direktori
  • Mengatur Daftar Kontrol Akses (ACL) sebuah berkas
  • Menetapkan ACL secara rekursif

Atur pengaturan ACL dari direktori

Dapatkan daftar kontrol akses (ACL) direktori dengan memanggil metode DataLakeDirectoryClient.GetAccessControlAsync dan atur ACL dengan memanggil metode DataLakeDirectoryClient.SetAccessControlList .

Contoh ini mendapatkan dan mengatur ACL direktori bernama my-directory. String user::rwx,group::r-x,other::rw- memberi pengguna pemilik izin baca, tulis, dan jalankan, memberi grup pemilik hanya izin baca dan jalankan, dan memberi semua izin baca dan tulis lainnya.

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);

}

Anda juga bisa mendapatkan dan mengatur ACL direktori root kontainer. Untuk mendapatkan direktori akar, berikan string kosong ("") ke metode DataLakeFileSystemClient.GetDirectoryClient .

Mengatur Daftar Kontrol Akses (ACL) sebuah berkas

Dapatkan daftar kontrol akses (ACL) file dengan memanggil metode DataLakeFileClient.GetAccessControlAsync dan atur ACL dengan memanggil metode DataLakeFileClient.SetAccessControlList .

Contoh ini mendapatkan dan mengatur ACL file bernama my-file.txt. String user::rwx,group::r-x,other::rw- memberi pengguna pemilik izin baca, tulis, dan jalankan, memberi grup pemilik hanya izin baca dan jalankan, dan memberi semua izin baca dan tulis lainnya.

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);
}

Menetapkan ACL secara rekursif

Atur ACL secara rekursif dengan memanggil metode DataLakeDirectoryClient.SetAccessControlRecursiveAsync . Sampaikan kepada metode ini sebuah Daftar dari PathAccessControlItem. Setiap PathAccessControlItem mendefinisikan entri ACL.

Jika Anda ingin mengatur entri ACL default , maka Anda dapat mengatur properti PathAccessControlItem.DefaultScope dari PathAccessControlItem ke true.

Contoh ini mengatur ACL direktori dengan nama my-parent-directory. Metode ini menerima parameter boolean dengan nama isDefaultScope yang menentukan apakah akan mengatur ACL default. Parameter tersebut digunakan dalam konstruktor PathAccessControlItem. Entri ACL memberi pengguna pemilik izin baca, tulis, dan eksekusi, memberi grup pemilik hanya izin baca dan eksekusi, dan tidak memberi akses ke semua orang lain. Entri ACL terakhir dalam contoh ini memberikan izin baca dan eksekusi kepada pengguna tertentu dengan ID objek 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);
}

Perbarui ACL

Saat memperbarui ACL, Anda mengubah ACL, dan bukan mengganti ACL. Misalnya, Anda dapat menambahkan perwakilan keamanan baru ke ACL tanpa memengaruhi perwakilan keamanan lain yang tercantum dalam ACL. Untuk mengganti ACL alih-alih memperbaruinya, lihat bagian Atur ACL di artikel ini.

Bagian ini memperlihatkan kepada Anda cara:

  • Perbarui ACL
  • Perbarui ACL secara berulang

Perbarui ACL

Pertama, dapatkan ACL direktori dengan memanggil metode DataLakeDirectoryClient.GetAccessControlAsync . Salin daftar entri ACL ke Daftar objek PathAccessControl baru. Lalu temukan entri yang ingin Anda perbarui lalu ganti di dalam daftar. Atur ACL dengan memanggil metode DataLakeDirectoryClient.SetAccessControlList .

Contoh ini memperbarui ACL akar kontainer dengan mengganti entri ACL untuk semua pengguna lain.

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);
    }

   }

Perbarui ACL secara berulang

Untuk memperbarui ACL secara rekursif, buat objek ACL baru dengan entri ACL yang ingin Anda perbarui, lalu gunakan objek tersebut dalam operasi pembaruan ACL. Jangan mengambil ACL yang sudah ada, cukup berikan entri ACL yang perlu diperbarui.

Perbarui ACL secara rekursif dengan memanggil metode DataLakeDirectoryClient.UpdateAccessControlRecursiveAsync . Sampaikan kepada metode ini sebuah Daftar dari PathAccessControlItem. Setiap PathAccessControlItem mendefinisikan entri ACL.

Jika Anda ingin memperbarui entri ACL default , maka Anda dapat mengatur properti PathAccessControlItem.DefaultScope dari PathAccessControlItem ke true.

Contoh ini memperbarui entri ACL dengan izin tulis. Metode ini menerima parameter boolean bernama isDefaultScope yang menentukan apakah akan memperbarui ACL default. Parameter tersebut digunakan dalam konstruktor 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);

}

Hapus entri ACL

Anda bisa menghapus satu atau beberapa entri ACL. Bagian ini memperlihatkan kepada Anda cara:

  • Menghapus entri ACL
  • Hapus entri ACL secara rekursif

Menghapus entri ACL

Pertama, dapatkan ACL direktori dengan memanggil metode DataLakeDirectoryClient.GetAccessControlAsync . Salin daftar entri ACL ke Daftar objek PathAccessControl baru. Kemudian temukan entri yang ingin Anda hapus dan panggil metode Hapus koleksi. Atur ACL yang diperbarui dengan memanggil metode DataLakeDirectoryClient.SetAccessControlList .

Contoh ini memperbarui ACL akar kontainer dengan mengganti entri ACL untuk semua pengguna lain.

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);
    }

}

Hapus entri ACL secara rekursif

Untuk menghapus entri ACL secara rekursif, buat objek ACL baru untuk entri ACL yang akan dihapus, lalu gunakan objek tersebut dalam operasi hapus ACL. Jangan mengambil ACL yang ada, cukup berikan hanya entri ACL yang akan dihapus.

Hapus entri ACL dengan memanggil metode DataLakeDirectoryClient.RemoveAccessControlRecursiveAsync . Sampaikan kepada metode ini sebuah Daftar dari PathAccessControlItem. Setiap PathAccessControlItem mendefinisikan entri ACL.

Jika Anda ingin menghapus entri ACL default , maka Anda dapat mengatur properti PathAccessControlItem.DefaultScope dari PathAccessControlItem ke true.

Contoh ini menghapus entri ACL dari ACL direktori dengan nama my-parent-directory. Metode ini menerima parameter boolean dengan nama isDefaultScope yang menentukan apakah akan menghapus entri dari ACL default. Parameter tersebut digunakan dalam konstruktor 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);

}

Memulihkan dari kegagalan

Anda mungkin mengalami kesalahan runtime atau izin saat memodifikasi ACL secara rekursif. Untuk kesalahan runtime, mulai ulang proses dari awal. Kesalahan izin dapat terjadi jika perwakilan keamanan tidak memiliki izin yang memadai untuk mengubah ACL direktori atau file yang ada dalam hierarki direktori yang sedang dimodifikasi. Atasi masalah izin, lalu pilih untuk melanjutkan proses dari titik kegagalan menggunakan token kelanjutan, atau mulai ulang proses dari awal. Anda tidak perlu menggunakan token kelanjutan jika Anda lebih memilih memulai ulang dari awal. Anda dapat menerapkan ulang entri ACL tanpa dampak negatif.

Contoh ini mengembalikan token kelanjutan jika terjadi kegagalan. Aplikasi dapat memanggil metode contoh ini lagi setelah kesalahan telah diatasi, dan meneruskan token kelanjutan. Jika metode contoh ini dipanggil untuk pertama kalinya, aplikasi dapat meloloskan nilai null untuk parameter token kelanjutan.

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;
    }

}

Jika Anda ingin proses selesai tanpa gangguan oleh kesalahan izin, Anda bisa menentukannya.

Untuk memastikan bahwa proses selesai tanpa gangguan, teruskan objek AccessControlChangedOptions dan atur properti ContinueOnFailure objek tersebut ke true.

Contoh ini menetapkan entri ACL secara rekursif. Jika kode ini menemui kesalahan izin, maka akan merekam kegagalan tersebut dan melanjutkan eksekusi. Contoh ini mencetak jumlah kegagalan pada konsol.

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());
}

Praktik terbaik

Bagian ini menyediakan beberapa panduan praktik terbaik untuk mengatur ACL secara rekursif.

Menangani kesalahan runtime

Kesalahan runtime dapat terjadi karena berbagai alasan (Misalnya: ketidaktersediaan atau masalah konektivitas klien). Jika Anda mengalami kesalahan runtime, mulai ulang proses ACL rekursif. ACL dapat diterapkan kembali ke item tanpa menyebabkan dampak negatif.

Menangani kesalahan izin (403)

Jika Anda menemukan pengecualian kontrol akses saat menjalankan proses ACL rekursif, prinsip keamanan AD Anda mungkin tidak memiliki izin yang memadai untuk menerapkan ACL ke satu atau beberapa item anak dalam hierarki direktori. Ketika kesalahan izin terjadi, proses berhenti dan token kelanjutan disediakan. Perbaiki masalah izin, lalu gunakan token kelanjutan untuk memproses himpunan data yang tersisa. Direktori dan file yang telah berhasil diproses tidak perlu diproses lagi. Anda juga dapat memilih untuk memulai ulang proses ACL rekursif. ACL dapat diterapkan kembali ke item tanpa menyebabkan dampak negatif.

Credentials

Kami menyarankan agar Anda menyediakan entitas keamanan Microsoft Entra yang telah ditetapkan peran Pemilik Data Blob Penyimpanan dalam cakupan akun atau kontainer penyimpanan target.

Performance

Untuk mengurangi latensi, kami menyarankan Anda menjalankan proses ACL rekursif di Azure Virtual Machine (VM) yang terletak di wilayah yang sama dengan akun penyimpanan Anda.

Batas ACL

Jumlah maksimum ACL yang dapat Anda terapkan ke direktori atau file adalah 32 ACL akses dan 32 ACL default. Untuk informasi selengkapnya, lihat Kontrol akses di Azure Data Lake Storage Gen2.

Lihat juga