CIAM 102: 授權與基於角色的存取控制
組織和租戶對於群組身份來說是很棒的,但它們導致了一種絕對民主狀態:每個人在這個系統中都可以做任何事。雖然烏托邦仍然是個謎,我們來看看存取治理:授權(AuthZ)。
背景
在 前一篇文章 中,我們介紹了認證(AuthN)和授權(AuthZ)的概念,以及一些令人頭疼的術語:身份、組織、租戶等。
組織和租戶對於群組身份來說是很棒的,但它們導致了一種絕對民主狀態:每個人在這個系統中都可以做任何事。雖然烏托邦仍然是個謎,我們來看看存取治理:授權(AuthZ)。
為什麼我們需要授權?
Notion 是一個很好的例子。對於你擁有的每個頁面,你可以選擇只讓自己看到、與朋友共享,甚至公開共享。
或者,對於一家線上書店,你希望每個人都可以看到所有書籍,但客戶只能看到自己的訂單,而賣家只能管理自己店鋪中的書籍。
AuthZ 和 AuthN 是複雜商業模式的基本組成部分。它們經常一起運作;AuthZ 驗證用戶的存取,而 AuthN 認證身份。兩者對於系統安全都很必要。
基本授權模型
這是最常見的 AuthZ 模型之一:如果 IDENTITY 在 RESOURCE 上執行 ACTION,則 ACCEPT 或 DENY。
在 Notion 的例子中,模型為 PERSON 在 PAGE 上執行 VIEW。
如果頁面是私密的:
- 當你在你的 PAGE 上執行 VIEW 時,你會收到 ACCEPT。
- 其他人在你的 PAGE 上執行 VIEW 時應該收到 DENY。
基於共識,業界開發了各種授權技術,如基於角色的存取控制(RBAC)、基於屬性的存取控制(ABAC)。今天,我們會專注於 NIST RBAC 模型 的第一級:扁平 RBAC。
基於角色的存取控制
讓我們擴展書店的例子。假設我們有很多顧客,但只有一個賣家:
- 顧客可以查看和訂購書籍,以及查看自己的訂單。
- 賣家可以查看、創建和刪除書籍,並管理客戶訂單。
定義資源
在 Logto 中,資源(即 API 資源)通常表示一組實體或項目,因為需要使用有效的 URL 作為指標。因此我們定義了兩個資源:
- 書籍:
https://api.bookstore.io/books
- 訂單:
https://api.bookstore.io/orders
強制使用 URL 格式的一個優點是,它可以映射到你的 API 服務的實際地址,這在與系統中其他組件集成時提高了可讀性和辨識性。
定義權限
由於我們引入了資源的概念,在 Logto 中,我們還強制權限必須屬於資源,相反地,資源可以有權限。
讓我們為資源添加一些權限:
- 書籍:
read
,create
,delete
- 訂單:
read
,read:self
,create:self
,delete
雖然權限名稱沒有要求,但我們有以下慣例:
當 <action>
是必需用來描述權限時,:<target>
可以忽略以描述一般目標,即資源中的所有實體或項目。例如:
- 權限
read
在資源書籍中意味著可以閱讀任意書籍的動作。 - 權限
create:self
在資源訂單中意味著可以創建屬於當前用戶的訂單的動作。
定義角色
簡而言之,角色是一組權限。讓我們創建兩個角色 customer
和 seller
並為它們分配權限如下:
你可能注意到權限-角色分配是多對多關係。
將角色分配給用戶
就像角色-權限分配一樣,用戶-角色分配也是多對多關係。因此,你可以為一個用戶分配多個角色,一個角色也可以分配給多個用戶。
連接點
這是 Logto 中第一級 RBAC 模型的完整關係圖:
在 RBAC 模型中,權限總是 "正向" 的,意味著授權判斷很簡單:如果用戶擁有權限,則接受;否則拒絕。
我們假設 Alice 有角色 seller
,Bob 和 Carol 有角色 customer
。我們將首先用自然語言描述動作,並將它們翻譯成標準授權格式:IDENTITY 在 RESOURCE 上執行 ACTION,最終得出結論。
- Alice 想要添加一個新書進行銷售:
- 用戶 Alice 在資源書籍(
https://api.bookstore.io/books
)上執行create
。 - 由於 Alice 根據她的角色
seller
被分配了書籍的create
權限,結果是 ✅ 接受。
- 用戶 Alice 在資源書籍(
- Alice 想要查看所有訂單以確定銷售是否符合預期:
- 用戶 Alice 在資源訂單(
https://api.bookstore.io/orders
)上執行read
。 - 由於 Alice 根據她的角色
seller
被分配了訂單的read
權限,結果是 ✅ 接受。
- 用戶 Alice 在資源訂單(
- Bob 想要瀏覽書籍列表以查看是否有他想購買的書籍。
- 用戶 Bob 在資源書籍(
https://api.bookstore.io/books
)上執行read
。 - 由於 Bob 根據他的角色
customer
被分配了書籍的read
權限,結果是 ✅ 接受。
- 用戶 Bob 在資源書籍(
- Bob 想查看 Carol 的訂單。
- 由於這是別人的訂單,訂單的
read:self
權限在這裡不起作用。 - 用戶 Bob 在資源訂單(
https://api.bookstore.io/order
)上執行read
。 - 由於 Bob 沒有訂單的
read
權限,結果是 ❌ 拒絕。
- 由於這是別人的訂單,訂單的
其他 RBAC 級別
NIST RBAC 模型有四個級別:
- 扁平 RBAC
- 層次化 RBAC
- 受限 RBAC
- 對稱 RBAC
如果你感興趣,請參閱 論文 以了解更多詳情。
Logto 現在已有第一級實現,將根據社群反饋來進展到更高級別。如果更高級別符合你的需求,請隨時告訴我們!
實踐中
除了理論,我們仍然需要大量技術工作以確保模型按預期運作:
- 客戶端和身份驗證服務器開發
- RBAC 的數據庫設計
- 不同服務間的驗證
- 安全性和開放標準符合性
- 角色、權限、資源的管理和分配
不要驚慌。我們已考慮到這一點,並增加了開箱即用的支持來涵蓋以上所有事項。 查看 🔐 RBAC 食譜 以了解如何在 Logto 中使用 RBAC。
結語
對於大多數案例來說,RBAC 是一種強大的存取管理模型,但並不是萬能解決方案。我們仍然有一些問題:
- 我需要高級別的 RBAC 嗎?
- RBAC 與其他授權模型相比如何?
- 如何在不同的組織間定義授權模型?