Azure Data Lake Storage 中的存取控制清單 (ACL)
Azure Data Lake Storage 可實作支援 Azure 角色型存取控制 (Azure RBAC) 和 POSIX 型存取控制清單 (ACL) 的存取控制模型。 本文說明 Data Lake Storage 中的存取控制清單。 若要瞭解如何將 Azure RBAC 與 ACL 整合,以及系統如何評估加以評估來進行授權決策,請參閱 Azure Data Lake Storage 中的存取控制模型。
關於 ACL
您可以將安全性主體與檔案和目錄的存取層級建立關聯。 每個關聯都會捕捉為存取控制清單 (ACL) 中的輸入項。 儲存體帳戶中的每個檔案和目錄都具有存取控制清單。 當安全性主體嘗試在檔案或目錄上執行作業時,ACL 檢查會判斷該安全性主體 (使用者、群組、服務主體或受控識別) 是否有相應的權限等級來執行此作業。
注意
ACL 僅適用於相同租用戶中的安全性主體。 ACL 不適用於使用共用金鑰授權的使用者,因為沒有身分識別與呼叫者相關聯,因此無法執行以安全性主體權限為基礎的授權。 對於共用存取簽章 (SAS) 權杖也是如此,除非使用使用者委派的 SAS 權杖。 在此情況下,只要使用選擇性參數 suoid,Azure 儲存體就會在授權操作之前對物件 ID 執行 POSIX ACL 檢查。 若要深入了解,請參閱建構使用者委派 SAS。
如何設定 ACL
若要設定檔案和目錄層級權限,請參閱下列任何文章:
環境 | 文章 |
---|---|
Azure 儲存體總管 | 使用 Azure 儲存體總管來管理 Azure Data Lake Storage 中的 ACL |
Azure 入口網站 | 使用 Azure 入口網站管理 Azure Data Lake Storage 中的 ACL |
.NET | 使用 .NET 管理 Azure Data Lake Storage 中的 ACL |
Java | 使用 Java 管理 Azure Data Lake Storage 中的 ACL |
Python | 使用 Python 管理 Azure Data Lake Storage 中的 ACL |
JavaScript (Node.js) | 使用 Node.js 中的 JavaScript SDK 來管理 Azure Data Lake Storage 中的 ACL |
PowerShell | 使用 PowerShell 管理 Azure Data Lake Storage 中的 ACL |
Azure CLI | 使用 Azure CLI 管理 Azure Data Lake Storage 中的 ACL |
REST API | 路徑 - 更新 |
重要
如果安全性主體是服務主體,請務必使用服務主體的物件識別碼,而不是相關應用程式註冊的物件識別碼。 若要取得服務主體的物件識別碼,請開啟 Azure CLI,然後使用此命令:az ad sp show --id <Your App ID> --query objectId
。 請務必將預留位置 <Your App ID>
取代為應用程式註冊的應用程式識別碼。 服務主體會被視為具名使用者。 您將將此識別碼新增至 ACL,就像任何具名使用者一樣。 本文稍後將說明具名使用者。
ACL 的類型
存取控制清單有兩種類型:存取 ACL 和預設 ACL。
存取 ACL 可控制對物件的存取。 檔案和目錄都有存取 ACL。
預設 ACL 是目錄相關聯 ACL 的範本,用以判斷在該目錄下所建立任何子項目的存取 ACL。 檔案沒有預設 ACL。
存取 ACL 和預設 ACL 都有相同的結構。
注意
變更上層的預設 ACL 不會影響已存在下層項目的存取 ACL 或預設 ACL。
權限層級
容器中目錄和檔案的權限為 [讀取]、[寫入] 和 [執行],這些權限可以用於下表所示的檔案和目錄:
檔案 | Directory | |
---|---|---|
讀取 (R) | 可以讀取檔案的內容 | 需要 [讀取] 和 [執行] 才能列出目錄內容 |
寫入 (W) | 可以寫入或附加至檔案 | 需要 [寫入] 和 [執行] 才能在目錄中建立子項目 |
執行 (X) | 不表示 Data Lake Storage 的內容中的任何項目 | 周遊目錄子項目的必要項目 |
注意
如果您只使用 ACL (沒有 Azure RBAC) 來授與權限,然後將檔案的讀取或寫入存取權授與安全性主體,則必須將容器的根資料夾 [執行] 權限授與安全性主體,以及會導向檔案的資料夾階層中的每個資料夾。
權限的簡短形式
RWX 用來表示 [讀取 + 寫入 + 執行]。 有更壓縮的數字形式存在,其中 [讀取 = 4]、[寫入 = 2] 和 [執行 = 1],其總和代表各種權限。 以下有一些範例。
數值形式 | 簡短形式 | 代表的意義 |
---|---|---|
7 | RWX |
讀取 + 寫入 + 執行 |
5 | R-X |
讀取 + 執行 |
4 | R-- |
參閱 |
0 | --- |
沒有權限 |
權限繼承
在 Data Lake Storage 所使用的 POSIX 樣式模型中,項目的權限會儲存在項目本身。 換句話說,如果在下層項目建立之後設定權限,就無法從上層項目繼承項目的權限。 只有在下層項目建立之前,上層項目已設定預設權限時,才會繼承權限。
ACL 權限相關的常見案例
下表顯示啟用安全性主體以執行 [作業] 資料行中所列作業所需的 ACL 輸入項。
下表顯示代表虛構目錄階層各層級的資料行。 容器 (/
) 的根目錄有一個資料行、有一個名為 Oregon 的子目錄、Oregon 目錄中有一個名為 Portland 的子目錄,Portland 目錄中有一個名為 Data.txt 的文字檔案。
重要
下表假設您只使用 ACL,而不使用任何 Azure 角色指派。 若要查看結合 Azure RBAC 與 ACL 的類似資料表,請參閱權限資料表:結合 Azure RBAC、ABAC 和 ACL。
作業 | / | Oregon/ | Portland/ | Data.txt |
---|---|---|---|---|
Read Data.txt | --X |
--X |
--X |
R-- |
Append to Data.txt | --X |
--X |
--X |
RW- |
Delete Data.txt | --X |
--X |
-WX |
--- |
刪除 /俄勒岡州/ | -WX |
RWX |
RWX |
--- |
刪除/俄勒岡州/波特蘭/ | --X |
-WX |
RWX |
--- |
Create Data.txt | --X |
--X |
-WX |
--- |
List / | R-X |
--- |
--- |
--- |
List /Oregon/ | --X |
R-X |
--- |
--- |
List /Oregon/Portland/ | --X |
--X |
R-X |
--- |
刪除檔案和目錄
如上表所示,只要目錄權限設定正確,刪除檔案就不需要寫入權限。 但是要刪除目錄及其所有內容,父目錄必須具有寫入 + 執行權限。 要刪除的目錄及其中的每個目錄,都需要 [讀取 + 寫入 + 執行] 權限。
注意
決不可刪除根目錄「/」。
使用者和身分識別
每個檔案和目錄都有這些身分識別的不同權限︰
- 擁有的使用者
- 擁有群組
- 具名使用者
- 具名群組
- 具名服務主體
- 具名受控識別
- 所有其他使用者
使用者和群組的身分識別是 Microsoft Entra 身分識別。 因此,除非另有註明,否則 Data Lake Storage 中的使用者可能表示 Microsoft Entra 使用者、服務主體、受控識別或安全性群組。
超級使用者
超級使用者擁有所有使用者的大多數權限。 超級使用者:
具有所有檔案和資料夾的 RWX 權限。
可以變更任何檔案或資料夾的權限。
可以變更任何檔案或資料夾的擁有使用者或擁有群組。
如果容器、檔案或目錄是使用共用金鑰、帳戶 SAS 或服務 SAS 建立的,則擁有者和擁有群組會設定為 $superuser
。
擁有的使用者
建立項目的使用者會自動成為項目的擁有使用者。 擁有使用者可以︰
- 變更所擁有檔案的權限。
- 只要擁有使用者也是目標群組的成員,請變更所擁有檔案的擁有群組。
注意
擁有使用者「無法」變更檔案或目錄的擁有使用者。 只有超級使用者可以變更檔案或目錄的擁有使用者。
擁有群組
在 POSIX ACL 中,每個使用者都與主要群組相關聯。 例如,使用者 "Alice" 可能屬於 "finance" 群組。 Alice 也可能屬於多個群組,但一定有一個群組指定為其主要群組。 在 POSIX 中,當 Alice 會建立檔案時,該檔案的擁有群組會設定為她的主要群組,在此案例中為 "finance"。除此之外,擁有群組的作用類似於指派給其他使用者/群組的權限。
指派新檔案或目錄的擁有群組
- 案例 1:根目錄
/
。 在建立 Data Lake Storage 容器時,即會建立此目錄。 在此案例中,擁有群組會設定為建立容器的使用者 (如果該容器是使用 OAuth 建立的)。 如果容器是使用共用金鑰、帳戶 SAS 或服務 SAS 建立的,則擁有者和擁有群組會設定為$superuser
。 - 案例 2 (其他所有案例):建立新項目時,會從父目錄複製擁有群組。
變更擁有群組
可以變更擁有群組的對象︰
- 任何超級使用者。
- 擁有使用者,如果擁有使用者也是目標群組的成員。
注意
擁有群組無法變更檔案或目錄的 ACL。 雖然在上述根目錄的案例 (案例 1) 中,擁有群組設定為建立帳戶的使用者,但單一使用者帳戶並無法透過擁有群組來提供權限。 您可以將此權限指派給有效的使用者群組 (如果適用的話)。
如何評估權限
系統會以下列順序評估身分識別:
- 超級使用者
- 擁有使用者
- 具名使用者、服務主體或受控識別
- 擁有群組或具名群組
- 所有其他使用者
如果將一個以上的身分識別套用到安全性主體,則會授予與第一個身分識別相關聯的權限層級。 例如,如果安全性主體同時是擁有使用者和具名使用者,則會套用與擁有使用者相關聯的權限層級。
具名群組皆同時考慮。 如果安全性主體是多個具名群組的成員,則在授與所需的權限之前,系統會評估每個群組。 如果沒有任何具名群組提供所需的權限,則系統會繼續根據與所有其他使用者相關聯的權限評估要求。
以下的虛擬程式碼代表儲存體帳戶的存取檢查演算法。 此演算法會顯示身分識別的評估順序。
def access_check( user, desired_perms, path ) :
# access_check returns true if user has the desired permissions on the path, false otherwise
# user is the identity that wants to perform an operation on path
# desired_perms is a simple integer with values from 0 to 7 ( R=4, W=2, X=1). User desires these permissions
# path is the file or directory
# Note: the "sticky bit" isn't illustrated in this algorithm
# Handle super users.
if (is_superuser(user)) :
return True
# Handle the owning user. Note that mask isn't used.
entry = get_acl_entry( path, OWNER )
if (user == entry.identity)
return ( (desired_perms & entry.permissions) == desired_perms )
# Handle the named users. Note that mask IS used.
entries = get_acl_entries( path, NAMED_USER )
for entry in entries:
if (user == entry.identity ) :
mask = get_mask( path )
return ( (desired_perms & entry.permissions & mask) == desired_perms)
# Handle named groups and owning group
member_count = 0
perms = 0
entries = get_acl_entries( path, NAMED_GROUP | OWNING_GROUP )
mask = get_mask( path )
for entry in entries:
if (user_is_member_of_group(user, entry.identity)) :
if ((desired_perms & entry.permissions & mask) == desired_perms)
return True
# Handle other
perms = get_perms_for_other(path)
mask = get_mask( path )
return ( (desired_perms & perms & mask ) == desired_perms)
遮罩
如<存取檢查演算法>所述,遮罩會限制具名使用者、擁有群組及具名群組的存取權。
對於新的 Data Lake Storage 容器,根目錄 ("/") 的存取 ACL 遮罩會預設為 750 (目錄) 和 640 (檔案)。 下表顯示這些權限層級的符號標記法。
實體 | Directories | 檔案 |
---|---|---|
擁有使用者 | rwx |
rw- |
擁有群組 | r-x |
r-- |
其他 | --- |
--- |
檔案不會接收 X 位元,因為它與僅限儲存的系統中包含的檔案無關。
遮罩可就個別的呼叫指定。 這可讓不同的取用系統 (例如叢集) 將不同的有效遮罩用於其檔案作業上。 指定於給定要求上的遮罩會完全覆寫預設遮罩。
黏性位元
黏性位元是 POSIX 容器的更進階功能。 在 Data Lake Storage 的內容中,不太可能需要黏性位元。 總而言之,如果已在目錄上啟用黏性位元,子項目便只能由子項目的擁有使用者、目錄擁有者或超級使用者 ($superuser) 刪除或重新命名。
黏性位元不會顯示在 Azure 入口網站中。 若要深入了解黏性位元及其設定方式,請參閱什麼是黏性位元 Data Lake Storage?。
新檔案和目錄的預設權限
在現有目錄下建立新的檔案或目錄時,上層目錄的預設 ACL 會決定:
- 下層目錄的預設 ACL 和存取 ACL。
- 子檔案的存取 ACL (檔案沒有預設 ACL)。
umask
建立預設 ACL 時,umask 會套用至存取 ACL,以判斷預設 ACL 的初始權限。 如果在父目錄上定義預設 ACL,則會有效地忽略 umask,並改用父目錄的預設 ACL 來定義這些初始值。
umask 是父目錄上的一個 9 位元值,其中包含用於擁有使用者、擁有群組及其他的 RWX 值。
Azure Data Lake Storage 的 umask 是一個設定為 007 的常數值。 此值會轉譯成:
umask 元件 | 數值形式 | 簡短形式 | 意義 |
---|---|---|---|
umask.owning_user | 0 | --- |
針對擁有使用者,將父代的存取 ACL 複製到子系的預設 ACL |
umask.owning_group | 0 | --- |
針對擁有群組,將父代的存取 ACL 複製到子系的預設 ACL |
umask.other | 7 | RWX |
針對其他,移除子系存取 ACL 上的所有權限 |
常見問題集
我必須啟用 ACL 的支援嗎?
否。 只要階層命名空間 (HNS) 功能開啟,就會為儲存體帳戶啟用透過 ACL 的存取控制。
如果 HNS 關閉,Azure RBAC 授權規則仍適用。
套用 ACL 的最佳方式為何?
請一律使用 Microsoft Entra 安全性群組作為 ACL 項目中的指派主體。 抵制直接指派個別使用者或服務主體的機會。 使用此結構將可讓您新增和移除使用者或服務主體,而不需要將 ACL 重新套用至整個目錄結構。 相反地,您可以直接從適當的 Microsoft Entra 安全性群組新增或移除使用者和服務主體。
有許多不同方式可以設定群組。 例如,假設您有一個名為 /LogData 的目錄,該目錄會保存伺服器產生的記錄資料。 Azure Data Factory (ADF) 會將資料內嵌至該資料夾內。 服務工程小組的特定使用者會上傳記錄並管理此資料夾的其他使用者,而各種 Databricks 叢集會分析該資料夾中的記錄。
若要啟用這些活動,您可以建立 LogsWriter
群組和 LogsReader
群組。 然後,您可以依下述步驟指派權限:
- 將
LogsWriter
群組新增至具有rwx
權限的 /LogData 目錄的 ACL。 - 將
LogsReader
群組新增至具有r-x
權限的 /LogData 目錄的 ACL。 - 將服務主體物件或適用於 ADF 的受控服務識別 (MSI) 新增至
LogsWriters
群組。 - 將服務工程團隊中的使用者新增至
LogsWriter
群組。 - 將 Databricks 的服務主體物件或 MSI 新增至
LogsReader
群組。
如果服務工程團隊中的使用者離開公司,您可以直接從群組中 LogsWriter
移除。 如果您未將該使用者新增至群組,而是為該使用者新增專用的 ACL 項目,則必須從 /LogData 目錄中移除該 ACL 項目。 您也必須從 /LogData 目錄的所有目錄階層中的所有子目錄和檔案中移除該項目。
若要建立群組並新增使用者,請參閱使用 Microsoft Entra ID 建立群組並新增成員。
重要
Azure Data Lake Storage Gen2 會依賴 Microsoft Entra ID 來管理安全性群組。 Microsoft Entra ID 建議您將指定安全性主體的群組成員資格限制為小於 200。 這項建議是因為 JSON Web 權杖 (JWT) 的限制,而 JWT 則是在 Microsoft Entra 應用程式中提供安全性主體的群組成員資格資訊。 超過此限制可能會導致 Data Lake Storage Gen2 發生非預期的效能問題。 若要深入了解,請參閱使用 Microsoft Entra ID 設定應用程式的群組宣告。
Azure RBAC 和 ACL 權限的評估方式為何?
若要瞭解系統如何一起評估 Azure RBAC 和 ACL,以進行儲存體帳戶資源的授權決策,請參閱如何評估權限。
Azure 角色指派和 ACL 項目有哪些限制?
下表提供摘要檢視:使用 Azure RBAC 來管理的「廣泛」權限 (套用至儲存體帳戶或容器之權限的摘要) 和使用 ACL 來管理的「精細」權限 (套用至檔案和目錄的權限)。 使用安全性群組以進行 ACL 指派。 藉由使用群組,您不太會超過每個訂用帳戶的角色指派數目上限,以及每個檔案或目錄的 ACL 項目數上限。
機制 | 範圍 | 限制 | 支援的權限層級 |
---|---|---|---|
Azure RBAC | 儲存體帳戶、容器。 訂用帳戶或資源群組層級的跨資源 Azure 角色指派。 |
訂用帳戶中 4000 個 Azure 角色指派 | Azure 角色 (內建或自訂) |
ACL | 目錄、檔案 | 每個目錄和每個檔案 32 個 ACL 項目 (實際上是 28 個 ACL 項目)。 存取和預設 ACL 各有各的 32 個 ACL 項目限制。 | ACL 權限 |
Data Lake Storage 是否支援 Azure RBAC 的繼承?
Azure 角色指派可以繼承。 指派會從訂用帳戶、資源群組和儲存體帳戶資源向下傳至容器資源。
Data Lake Storage 是否支援 ACL 的繼承?
預設 ACL 可以用來為父目錄下新建立的子目錄和檔案設定 ACL。 若要更新現有子項目的 ACL,您必須針對所需的目錄階層,以遞迴方式加入、更新或移除 ACL。 如需指引,請參閱本文的如何設定 ACL 一節。
若要以遞迴方式刪除目錄及其內容,需要哪些權限?
- 呼叫者具有「超級使用者」權限,
Or
- 父目錄必須具有 [寫入 + 執行] 權限。
- 要刪除的目錄及其中的每個目錄,都需要 [讀取 + 寫入 + 執行] 權限。
注意
您不需要寫入權限即可刪除目錄中的檔案。 此外,決不可刪除根目錄 "/"。
誰是檔案或目錄的擁有者?
檔案或目錄的建立者會成為擁有者。 如果是根目錄,這會是容器建立者的使用者身分識別。
在建立檔案或目錄時,會將哪個群組設定為擁有群組?
擁有群組是從新檔案或目錄建立所在父目錄的擁有群組複製而來的。
我是檔案的擁有使用者,但沒有我需要的 RWX 權限。 我該如何處理?
擁有使用者可以變更檔案的權限,以取得本身所需的任何 RWX 權限。
為什麼我有時候會在 ACL 中看到 GUID?
如果項目代表使用者,而使用者已不存在於 Microsoft Entra 中,則會顯示 GUID。 這種情形通常會發生在使用者已離開公司,或已在 Microsoft Entra ID 中刪除其帳戶時。 此外,服務主體和安全性群組並沒有使用者主體名稱 (UPN) 可資識別,因此會藉由其 OID 屬性 (GUID) 來顯示。 若要清除 ACL,請手動刪除這些 GUID 項目。
如何為服務主體正確設定 ACL?
當您為服務主體定義 ACL 時,請務必針對您所建立的應用程式註冊使用服務主體的物件識別碼 (OID)。 請務必注意,已註冊的應用程式在特定的 Microsoft Entra 租用戶中會有個別的服務主體。 註冊的應用程式具有 Azure 入口網站中可見的 OID,但服務主體具有另一個 (不同的) OID。
文章若要取得對應至應用程式註冊的服務主體 OID,您可以使用 az ad sp show
命令。 將應用程式識別碼指定為參數。 以下是取得服務主體的 OID 範例,該主體對應至應用程式標識碼 = 00001111-aaaa-2222-bbbb-3333cccc4444 的應用程式註冊。 在 Azure CLI 中執行以下命令:
az ad sp show --id 00001111-aaaa-2222-bbbb-3333cccc4444 --query objectId
OID 將會 顯示 。
當您有服務主體的正確 OID 時,請移至儲存體總管 [管理存取權] 頁面,以新增 OID 並為 OID 指派適當的權限。 請確定選取 [儲存]
我是否可以設定容器的 ACL?
否。 容器沒有 ACL。 不過,您可以設定容器根目錄的 ACL。 每個容器都有一個根目錄,且與容器共用相同名稱。 例如,如果容器名為 my-container
,則根目錄的名稱為 my-container/
。
Azure 儲存體 REST API 包含名為設定容器 ACL 的作業,但該作業無法用於設定容器的 ACL 或容器的根目錄。 相反地,該作業是用來指出是否可以使用匿名要求存取容器中的 Blob。 我們建議對 Blob 資料的所有要求進行授權驗證。 如需詳細資訊,請參閱概觀:補救 Blob 資料的匿名讀取存取。
何處可以進一步了解 POSIX 存取控制模型?
- Linux 上的 POSIX 存取控制清單
- HDFS 權限指南
- POSIX 常見問題集
- POSIX 1003.1 2008
- POSIX 1003.1 2013
- POSIX 1003.1 2016
- Ubuntu 上的 POSIX ACL