什麼是casbin
幾乎所有的系統在設計的時候都要有許可權管理的模組,如果每次開發都要重新實現一次許可權管理,光是想想就覺得無聊,程式設計師嘛能用輪子就用輪子,因此casbin
出現了。
casbin
是一個強大、高效的訪問控制庫。支援常用的多種訪問控制模型,如ACL/RBAC/ABAC
等。可以實現靈活的訪問許可權控制。同時,casbin
支援多種程式語言,Go/Java/Node/PHP/Python/.NET/Rust
。
casbin的特點
- 支援自定義請求的格式,預設的請求格式為
{subject, object, action}
。 - 具有訪問控制模型model和策略policy兩個核心概念。
- 支援RBAC中的多層角色繼承,不止主體可以有角色,資源也可以具有角色。
- 支援超級使用者,如
root
或Administrator
,超級使用者可以不受授權策略的約束訪問任意資源。 - 支援多種內建的操作符,如
keyMatch
,方便對路徑式的資源進行管理,如/foo/bar
可以對映到/foo*
不是casbin該管的事
- 身份認證 authentication(即驗證使用者的使用者名稱、密碼),casbin只負責訪問控制。應該有其他專門的元件負責身份認證,然後由casbin進行訪問控制,二者是相互配合的關係。
- 管理使用者列表或角色列表。 Casbin 認為由專案自身來管理使用者、角色列表更為合適, 使用者通常有他們的密碼,但是 Casbin 的設計思想並不是把它作為一個儲存密碼的容器。 而是儲存RBAC方案中使用者和角色之間的對映關係。
常用授權模型
ACL
ACL
是Access Control List
的縮寫,稱為訪問控制列表. 定義了誰可以對某個資料進行何種操作. 關鍵資料模型有: 使用者, 許可權.
ACL規則簡單, 也帶來一些問題: 資源的許可權需要在使用者間切換的成本極大; 使用者數或資源的數量增長, 都會加劇規則維護成本;
典型應用
- 檔案系統
檔案系統的檔案或資料夾定義某個賬號(user)或某個群組(group)對檔案(夾)的讀(read)/寫(write)/執行(execute)許可權.
- 網路訪問
防火牆: 伺服器限制不允許指定機器訪問其指定埠, 或允許特定指定伺服器訪問其指定幾個埠.
RBAC
RBAC
是Role-based access control
的縮寫, 稱為 基於角色的訪問控制. 核心資料模型有: 使用者, 角色, 許可權.
使用者具有角色, 而角色具有許可權, 從而表達使用者具有許可權.
由於有角色作為中間紐帶, 當新增使用者時, 只需要為使用者賦予角色, 使用者即獲得角色所包含的所有許可權.
RBAC
存在多個擴充套件版本, RBAC0
、RBAC1
、RBAC2
、RBAC3
。這些版本的詳細說明可以引數這裡。我們在實際專案中經常使用的是RBAC1
,即帶有角色繼承概念的RBAC模型。
ABAC
ABAC
是Attribute-based access control
的縮寫, 稱為基於屬性的訪問控制.
許可權和資源當時的狀態(屬性)有關, 屬性的值可以用於正向判斷(符合某種條件則通過), 也可以用於反向判斷(符合某種條件則拒絕):
典型應用
- 論壇的評論許可權, 當帖子是鎖定狀態時, 則不再允許繼續評論;
- Github 私有倉庫不允許其他人訪問;
- 發帖者可以編輯/刪除評論(如果是RBAC, 會為發帖者定義一個角色, 但是每個帖子都要新增一條使用者/發帖角色的記錄);
- 微信聊天訊息超過2分鐘則不再允許撤回;
- 12306 只有實名認證後的賬號才能購票;
- 已過期的付費賬號將不再允許使用付費功能;
實現一個簡單的ACL授權驗證模型
安裝
go get github.com/casbin/casbin
編寫模型檔案(Model.conf)
具體語法可以參考官方教程 Model語法
[request_definition]
r = sub, obj, act
[policy_definition]
p = sub, obj, act
[matchers]
m = r.sub == p.sub && r.obj == p.obj && r.act == p.act
[policy_effect]
e = some(where (p.eft == allow))
編寫策略檔案(Policy.csv)
p, dajun, data1, read
p, lizi, data2, write
上述檔案的具體意義如下
有一條p(策略)
,定義了dajun(sub), data1(obj), read(act)
,語義化就是dajun
可以對data1
執行read
方法
code
package main
import (
"fmt"
"log"
"github.com/casbin/casbin/v2"
)
func check(e *casbin.Enforcer, sub, obj, act string) {
ok, _ := e.Enforce(sub, obj, act)
if ok {
fmt.Printf("%s CAN %s %s\n", sub, act, obj)
} else {
fmt.Printf("%s CANNOT %s %s\n", sub, act, obj)
}
}
func main() {
e, err := casbin.NewEnforcer("./model.conf", "./policy.csv")
if err != nil {
log.Fatalf("NewEnforecer failed:%v\n", err)
}
check(e, "dajun", "data1", "read")
check(e, "lizi", "data2", "write")
check(e, "dajun", "data1", "write")
check(e, "dajun", "data2", "read")
}
至此一個簡單的ACL模型的demo就完成了
社群
官方網站:casbin.org
github地址:go-casbin
官方論壇:forum.casbin.com
QQ 群:546057381( Casbin 訪問控制討論群)
社群為多個語言的多個框架適配了相應的中介軟體,未來將會有更多框架支援,如果你希望參與貢獻,歡迎加入casbin社群
參考
本作品採用《CC 協議》,轉載必須註明作者和本文連結