golang gin 基於 Casbin 實現權限控制
最近在使用 golang gin 開發一套公司內部的人事管理系統,但是發現權限管理比之前搞的系統要複雜不少, 所以我想借機瞭解一下傳說中的 Casbin 權限控制庫,看看是否可以借鑑一下。
涉及權限控制的需求場景
-
人事部門負責人需要能看到所有的人事數據
-
人事部門的普通 HR,只能看到部分部門的人事數據。即只能看到自己負責的部門數據
-
IT 部門或者行政部門指定人員,能看到資產管理模塊的數據。即每個員工有哪些名下資產,顯示器,主機,桌子椅子之類的。方便離職時進行資產回收。
-
部門負責人能看到自己部門的所有員工數據,除了薪資相關的字段。且只有看的權限。不能修改和刪除。
-
員工個人能通過企業微信的授權登錄,查看自己的個人信息。包括姓名,工號,入職時間,部門,崗位等。能修改一些基礎信息等。
-
一個集團公司下,有多個子公司。每個子公司都有自己的 HR 系統。HR 系統的權限控制需要支持集團公司下的多租戶模式。
現有 gin route group 的缺陷
總感覺,我目前實用的 gin route group + middleware 的方式,無法滿足複雜的權限控制需求。 而且對於粒度更細的權限控制,無法做到靈活的配置。
我目前實現的系統,都是基於角色的權限控制。即每個角色對應一組權限。 還是不太靈活。
當然根源是,gin 沒有內置權限控制的功能,我自己實現的這套感覺很亂。我不知道規範的做法是怎樣的。 所以,需要找個開源的權限控制庫,學習參考一下。
Casbin 示例
policy.csv 文件內容
p, alice, /api/*, read
p, bob, /version, write
預定義一些策略,也可以存儲到數據庫, alice 可以訪問所有 /api 開頭的路徑,bob 只能訪問 /version 路徑。
go 代碼
// 加載模型與策略,也可以存儲到數據庫
e, err := casbin.NewEnforcer("path/to/model.conf", "path/to/policy.csv")
sub := "alice" // the user that wants to access a resource.
obj := "data1" // the resource that is going to be accessed.
act := "read" // the operation that the user performs on the resource.
ok, err := e.Enforce(sub, obj, act) //判斷用戶是否有權限
實際使用中,e.Enforce() 方法通常會在中間件 (middleware) 中調用,以便在處理請求之前進行權限檢查。
參考:
https://juejin.cn/post/7108533587292454949
Casbin 的功能簡介
一種基於元模型的訪問控制策略描述語言 PML (PERM modeling language) 及其實施機制 PML-EM (PML enforcement mechanism)
-
策略語言無關性
-
訪問控制模型無關性: 即支持多種訪問控制模型,如基於角色的訪問控制(RBAC)、基於屬性的訪問控制(ABAC)以及 BLP 模型等。
-
程序設計語言無關性
參考論文:
https://www.jos.org.cn/jos/article/pdf/5624
一些術語
-
訪問控制模型(Access Control Model):定義瞭如何對資源進行訪問控制的規則和方法。
-
訪問控制策略(Access Control Policy):具體的規則和策略,用於定義哪些用戶或角色可以訪問哪些資源以及可以執行哪些操作。
-
訪問控制列表(Access Control List, ACL):一種常見的訪問控制策略,列出了每個用戶或角色對特定資源的訪問權限。
-
角色(Role):一組權限的集合,用戶可以被分配到一個或多個角色中,以簡化權限管理。
-
權限(Permission):對資源的具體操作權限,如讀取、寫入、刪除等。
-
策略(Policy):定義了訪問控制的規則,通常包括主體(用戶或角色)、客體(資源)和操作(權限)。
-
策略引擎(Policy Engine):用於評估訪問控制策略並決定是否允許訪問的組件。
-
策略存儲(Policy Store):存儲訪問控制策略的地方,可以是文件、數據庫或其他存儲系統。
-
基於屬性訪問控制 (attribute-based access control, 簡稱 ABAC) 模型
-
基於角色訪問控制 (role-based access control, 簡稱 RBAC) 模型
-
PERM (Policy, Effect, Request, Matchers) 模型
-
策略描述語言 PML (PERM modeling language)
-
基於請求 (request)、策略 (policy)、匹配器 (matcher)、策略效果 (effect) 的訪問控制元模型 PERM (policy-effect-request-matcher)
-
策略實施機制 PML-EM (PML enforcement mechanism)
-
認證(Authentication): 在 Web 程序中對應的是 HTTP Status 401 錯誤
-
授權(Authorization): 在 Web 程序中對應的是 HTTP Status 403 錯誤
Casbin 入門介紹
https://casbin.org/docs/tutorials/
裏面有一堆高質量的介紹文檔,找幾篇讀讀,就能有個大概的瞭解。剩下的就是動手測試一下了。
Request 原語
一個訪問請求通常由經典的三元組構成:
-
Subject:請求的主體,通常是用戶或角色。
-
Object:請求的對象,通常是資源或數據。
-
Action:請求的操作,通常是對資源的具體操作,如讀取、寫入等。
Policy 原語 (策略規則) 類似,也是這三個部分。
ACL (Access Control List) 與 RBAC (Role-Based Access Control),ABAC (Attribute-Based Access Control) 的區別
-
ACL 需要存儲每個用戶對每個資源的權限,適用於用戶數量較少的場景。
-
RBAC 通過角色來管理權限,適用於用戶數量較多的場景。用戶可以被分配到一個或多個角色中,角色定義了一組權限。但是,不能做的很細粒度的控制。這也是我目前遇到的困擾。但是我感覺,就算在代碼中寫死部分細微的權限控制邏輯,也能滿足需求。唯一的問題就是對於管理員來說不可見,也不能靈活配置。例如,同樣是人事部門的角色,有的 HR 能修改一些基礎信息等,有的 HR 只能查看數據。
-
ABAC 通過屬性來管理權限,適用於需要更細粒度控制的場景。用戶、資源和環境的屬性可以用來定義訪問控制策略。
參考:
https://github.com/xizhibei/blog/issues/101
多租戶的支持
參考:
https://www.cnblogs.com/wang_yb/p/9987397.html
策略規則 Policy 存儲到數據庫的方法
保存到 CSV 不是一個好的選擇,應該存儲到數據庫中。這樣可以更靈活地管理和查詢策略規則。
否則,每次都需要登錄服務器,修改 CSV 文件,然後重啓服務,才能生效。這樣不夠靈活。
參考:
https://casbin.org/zh/docs/policy-storage/
這裏支持 Gorm MySQL 的適配器:
https://casbin.org/zh/docs/adapters
實際場景實用
https://www.cnblogs.com/studyzy/p/11380736.html
gin middleware 插件
https://casbin.org/zh/docs/middlewares
這裏推薦了兩個插件 authz (這個居然是 gin 官方的,不可思議) 和 go-casbin, 不過這麼簡單的 middleware,我感覺並不需要三方的實現。 不過可以參考一下代碼。
感想
-
涉及的概念比較多,需要耐心學習和理解,即便拿出半天時間來閱讀理解,都是值得的。
-
即便最後不使用 Casbin 作爲權限控制的實現,也能從中學到很多關於權限控制的設計思路和實現方式。
-
是否有簡化版的 casbin 實現,只保留策略規則的部分。
今天就到這裏吧,實在看不下去了,太枯燥了。
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/bRgdxew0sV-jqtIMbiWe3g