概念:
Casbin是什么?
- Casbin是一個訪問控制框架,可以支持多種訪問控制模型(如ACL、RBAC、ABAC等)
目的:
我們最終想要實現的效果:
- 可以控制某一個人/角色(sub)能否對某個資源(obj)進行某種行為(act)
配置文件:
配置文件有兩個:model file和policy file,分別用是訪問控制模型文件和權限注冊表
- 在model file中,我們可以修改和定制想要使用的模型,如ACL、RBAC或者是自己組合出一個更適合項目的模型
- 在policy file中,存放着被注冊的權限,用於表示某人/角色對某資源有某種行為的權限
1. model file:
# Request definition 定義了請求的格式
[request_definition]
r = sub, obj, act
# Policy definition 定義了權限的格式
[policy_definition]
p = sub, obj, act
# Policy effect 定義了什么情況下這個請求是被允許的
[policy_effect]
e = some(where (p.eft == allow))
# Matchers //定義了如何將請求和權限相匹配
[matchers]
m = r.sub == p.sub && r.obj == p.obj && r.act == p.act
Casbin使用PERM來描述一種模型(Policy、Effect、Request、Matcher),其中:
- sub:Subject——表示Request中的accessing entity,即 “是誰” 發起的請求
- obj :Object——表示Request中的accessed resource,即被請求訪問 “目標資源”
- act :Action——表示Request中的access method, 即請求要對資源 “做什么”
2. policy file:
p, bob, data2, write
p, alice, data1, read
p, alice, data1, write
p, alice, data2, read
第一行定義了一個權限,表明一個叫Alice的用戶/組可以對data1這個資源進行read操作
工作原理:
例如:用戶Alice想要read一下data1
-
由於在model file中我們定義了請求的格式,所以我們這次的請求應該寫為 alice,data1,read,分別對應了 r.sub、r.obj、 r.act
-
在model file中我們也定義了policy的格式,所以當我們從policy file中讀取出一行權限時,分別對應着p.sub、p.obj、p.act
-
根據matcher所定義的規則,將請求與權限進行匹配,若某policy匹配成功,則p.eft = allow
r.sub == p.sub 滿足條件的有三條權限(2、3、4 )
r.obj == p.obj 剩下的三條權限中滿足條件的有兩條(2,3)
r.act == p.act 剩下的兩條權限中滿足條件的有一條(2) -
根據policy_effect定義的規則返回最終結果,此處定義的規則為:任意一條policy匹配成功,則返回allow
最后,Alice如願read到了data1
何不復雜點?
例1:
用戶alice和bob同屬於一個名為admin的角色(分組),而admin角色可以對 “/v1”路徑下的所有資源進行任何操作!
model file:
[request_definition]
r = sub, obj, act
[policy_definition]
p = sub, obj, act
[role_definition]
g = _, _
[policy_effect]
e = some(where (p.eft == allow))
[matchers]
m = g(r.sub, p.sub) && keyMatch(r.obj, p.obj) && (r.act == p.act || p.act == "*")
policy file:
p, admin, /v1/*, *
g, alice, admin
g, bob, admin
例2:
加一個超級管理員?
[matchers]
m = g(r.sub, p.sub) && keyMatch(r.obj, p.obj) && (r.act == p.act || p.act == "*")|| r.sub == "root"
擴展補充
- 在[role_definition]中,g有兩種不同的寫法:
g = _, _ 表示用戶,角色
g2 = _, _, _ 表示用戶,角色,域 - Model的三種加載方式
- 從文件中加載:
e := casbin.NewEnforcer("examples/rbac_model.conf", "examples/rbac_policy.csv")
-
從代碼中加載:
// Initialize the model from Go code. m := casbin.NewModel() m.AddDef("r", "r", "sub, obj, act") m.AddDef("p", "p", "sub, obj, act") m.AddDef("g", "g", "_, _") m.AddDef("e", "e", "some(where (p.eft == allow))") m.AddDef("m", "m", "g(r.sub, p.sub) && r.obj == p.obj && r.act == p.act") // Load the policy rules from the .CSV file adapter. // 使用自己的 adapter 替換。 a := persist.NewFileAdapter("examples/rbac_policy.csv") // 創建一個 enforcer。 e := casbin.NewEnforcer(m, a)
從字符串中加載
// Initialize the model from a string.
text :=
`
[request_definition]
r = sub, obj, act
[policy_definition]
p = sub, obj, act
[role_definition]
g = _, _
[policy_effect]
e = some(where (p.eft == allow))
[matchers]
m = g(r.sub, p.sub) && r.obj == p.obj && r.act == p.act
`
m := NewModel(text)
// Load the policy rules from the .CSV file adapter.
// Replace it with your adapter to avoid files.
a := persist.NewFileAdapter("examples/rbac_policy.csv")
// Create the enforcer.
e := casbin.NewEnforcer(m, a)
-
Matcher中的函數
matcher內置了若干個函數來支持開發者更好的定制自己的模型,甚至可以使用我們自定義的函數。當前支持的函數如下:
函數 釋義 -
keyMatch(arg1, arg2) arg1為URL,如 /v1/admin/filerag2為URL或 模板,如:/v1/admin/返回arg1是否與arg2相匹配
-
keyMatch2(arg1, arg2) arg1為URL,如 /v1/admin/file2rag2為URL或 : 模板,如:/v1/admin/:file返回arg1是否與arg2相匹配
-
regexMatch(arg1, arg2) arg1為任意字符串,arg2為正則表達式返回arg1是否與arg2相匹配
-
ipMatch(arg1, arg2) arg1為IP地址 如 192.168.12.42arg2為iP地址或CIDR,如 192.168.12. 0/24返回arg1是否與arg2相匹配
添加自定義函數見 自定義函數
-
Casbin API (帶注釋)
https://blog.csdn.net/lk2684753/article/details/99680892 -
權限系統設計模型分析
見文檔【權限系統設計模型分析】
更多信息
Casbin使用PERM的方式來描述模型,這使得我們可以靈活的自定義出更加適合自己項目的訪問控制模型。
在[matchers]中,Casbin還提供了一些函數以方便匹配(如例1中使用的keyMatch(arg1, arg2))
官方文檔:https://casbin.org/docs/zh-CN/overview
在線編輯:https://casbin.org/en/editor