基于Casbin实现ABAC
最近同事在研究Casbin的權限設計,我們主要是考慮使用ABAC基于屬性的訪問控制,Casbin給的示例不多,于是自己寫了幾個示例。
首先我們看看提到ABAC時,一般描述如下:
ABAC被一些人稱為是權限系統設計的未來。
不同于常見的將用戶通過某種方式關聯到權限的方式,ABAC則是通過動態計算一個或一組屬性來是否滿足某種條件來進行授權判斷(可以編寫簡單的邏輯)。屬性通常來說分為四類:用戶屬性(如用戶年齡),環境屬性(如當前時間),操作屬性(如讀取)和對象屬性(如一篇文章,又稱資源屬性),所以理論上能夠實現非常靈活的權限控制,幾乎能滿足所有類型的需求。
例如規則:“允許所有班主任在上課時間自由進出校門”這條規則,其中,“班主任”是用戶的角色屬性,“上課時間”是環境屬性,“進出”是操作屬性,而“校門”就是對象屬性了。為了實現便捷的規則設置和規則判斷執行,ABAC通常有配置文件(XML、YAML等)或DSL配合規則解析引擎使用。
這里我們就以這個班主任上課進出校門為例,看看在Casbin下是如何實現的:
首先,我們定義用戶環境和對象,操作我們就直接用字符串
type Person struct{Role stringName string } type Gate struct{Name string } type Env struct{Time time.TimeLocation string } func (env *Env) IsSchooltime() bool{return env.Time.Hour()>=8&&env.Time.Hour()<=18 } 接下來我們根據這個權限描述,我們可以寫出如下的Casbin PERM模板: [request_definition] r = sub, obj, act, env[policy_definition] p = sub, obj,act[policy_effect] e = some(where (p.eft == allow))[matchers] m = r.sub.Role=='Teacher' && r.obj.Name=='School Gate' && r.act in('In','Out') && r.env.Time.Hour >=8 && r.env.Time.Hour <= 18 因為我們給Env對象定義了IsSchooltime方法,所以我們也可以把目標寫成如下,也是一樣的效果: [request_definition] r = sub, obj, act, env[policy_definition] p = sub, obj,act[policy_effect] e = some(where (p.eft == allow))[matchers] m = r.sub.Role=='Teacher' && r.obj.Name=='School Gate' && r.act in('In','Out') && r.env.IsSchooltime() 接下來我們構造兩個人,一個是學生Yun,一個是老師Devin,構造兩個門,一個是工廠大門,一個是學校大門,操作的方法我們就定義進門In和控制大門Control兩個操作,環境上我們定義一個是早上9點,一個是晚上23點。 完整代碼如下: func TestTeacherEnterSchoolGate() {p1 := Person{Role: "Student", Name: "Yun"}p2 := Person{Role: "Teacher", Name: "Devin"}persons := []Person{p1, p2}g1 := Gate{Name: "School Gate"}g2 := Gate{Name: "Factory Gate"}gates := []Gate{g1, g2}const modelText = ` [request_definition] r = sub, obj, act, env[policy_definition] p = sub, obj,act[policy_effect] e = some(where (p.eft == allow))[matchers] m = r.sub.Role=='Teacher' && r.obj.Name=='School Gate' && r.act in('In','Out') && r.env.Time.Hour >7 && r.env.Time.Hour <= 18 `//m = r.sub.Role=='Teacher' && r.obj.Name=='School Gate' && r.act in('In','Out') && r.env.IsSchooltime()m := model.Model{}m.LoadModelFromText(modelText)e := casbin.NewEnforcer(m)envs := []*Env{InitEnv(9), InitEnv(23)}for _, env := range envs {fmt.Println("\r\nTime:",env.Time.Local())for _, p := range persons {for _, g := range gates {pass := e.Enforce(p, g, "In", env)fmt.Println(p.Role, p.Name, "In", g.Name, pass)pass = e.Enforce(p, g, "Control", env)fmt.Println(p.Role,p.Name, "Control", g.Name, pass)}}} }func InitEnv(hour int) *Env{env:=&Env{}env.Time=time.Date(2019,8,20,hour,0,0,0,time.Local)return env } 最后,輸出結果如下: Time: 2019-08-20 09:00:00 +0800 CST Student Yun In School Gate false Student Yun Control School Gate false Student Yun In Factory Gate false Student Yun Control Factory Gate false Teacher Devin In School Gate true Teacher Devin Control School Gate false Teacher Devin In Factory Gate false Teacher Devin Control Factory Gate falseTime: 2019-08-20 23:00:00 +0800 CST Student Yun In School Gate false Student Yun Control School Gate false Student Yun In Factory Gate false Student Yun Control Factory Gate false Teacher Devin In School Gate false Teacher Devin Control School Gate false Teacher Devin In Factory Gate false Teacher Devin Control Factory Gate false我們可以看到,在上課時間早上9點,學生是禁止進出校門,而只有老師Devin的進校門操作被通過。而到了晚上23點,老師Devin也不允許進校門了。
這里需要注意的是,在一般的模板中,是沒有env這個環境變量的,我把它加到了request_definition的最后面寫成r = sub, obj, act, env,同時e.Enforce(sub,obj,act,env)需要按順序傳入4個參數。
我還會對Casbin的ABAC進一步的研究,各測試用例會發布到https://github.com/studyzy/abactest 有興趣的可以看看。
最后,關于Casbin采用的規則引擎為,https://github.com/Knetic/govaluate,編輯Matchers規則可以參考:https://github.com/Knetic/govaluate/blob/master/MANUAL.md
轉載于:https://www.cnblogs.com/studyzy/p/11380736.html
總結
以上是生活随笔為你收集整理的基于Casbin实现ABAC的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 为什么好学生,学不好编程?
- 下一篇: 国际化开发技术FAQ