基于Casbin实现ABAC
最近同事在研究Casbin的權(quán)限設(shè)計(jì),我們主要是考慮使用ABAC基于屬性的訪問控制,Casbin給的示例不多,于是自己寫了幾個(gè)示例。
首先我們看看提到ABAC時(shí),一般描述如下:
ABAC被一些人稱為是權(quán)限系統(tǒng)設(shè)計(jì)的未來。
不同于常見的將用戶通過某種方式關(guān)聯(lián)到權(quán)限的方式,ABAC則是通過動(dòng)態(tài)計(jì)算一個(gè)或一組屬性來是否滿足某種條件來進(jìn)行授權(quán)判斷(可以編寫簡(jiǎn)單的邏輯)。屬性通常來說分為四類:用戶屬性(如用戶年齡),環(huán)境屬性(如當(dāng)前時(shí)間),操作屬性(如讀取)和對(duì)象屬性(如一篇文章,又稱資源屬性),所以理論上能夠?qū)崿F(xiàn)非常靈活的權(quán)限控制,幾乎能滿足所有類型的需求。
例如規(guī)則:“允許所有班主任在上課時(shí)間自由進(jìn)出校門”這條規(guī)則,其中,“班主任”是用戶的角色屬性,“上課時(shí)間”是環(huán)境屬性,“進(jìn)出”是操作屬性,而“校門”就是對(duì)象屬性了。為了實(shí)現(xiàn)便捷的規(guī)則設(shè)置和規(guī)則判斷執(zhí)行,ABAC通常有配置文件(XML、YAML等)或DSL配合規(guī)則解析引擎使用。
這里我們就以這個(gè)班主任上課進(jìn)出校門為例,看看在Casbin下是如何實(shí)現(xiàn)的:
首先,我們定義用戶環(huán)境和對(duì)象,操作我們就直接用字符串
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 } 接下來我們根據(jù)這個(gè)權(quán)限描述,我們可以寫出如下的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 因?yàn)槲覀兘oEnv對(duì)象定義了IsSchooltime方法,所以我們也可以把目標(biāo)寫成如下,也是一樣的效果: [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() 接下來我們構(gòu)造兩個(gè)人,一個(gè)是學(xué)生Yun,一個(gè)是老師Devin,構(gòu)造兩個(gè)門,一個(gè)是工廠大門,一個(gè)是學(xué)校大門,操作的方法我們就定義進(jìn)門In和控制大門Control兩個(gè)操作,環(huán)境上我們定義一個(gè)是早上9點(diǎn),一個(gè)是晚上23點(diǎn)。 完整代碼如下: 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 } 最后,輸出結(jié)果如下: 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我們可以看到,在上課時(shí)間早上9點(diǎn),學(xué)生是禁止進(jìn)出校門,而只有老師Devin的進(jìn)校門操作被通過。而到了晚上23點(diǎn),老師Devin也不允許進(jìn)校門了。
這里需要注意的是,在一般的模板中,是沒有env這個(gè)環(huán)境變量的,我把它加到了request_definition的最后面寫成r = sub, obj, act, env,同時(shí)e.Enforce(sub,obj,act,env)需要按順序傳入4個(gè)參數(shù)。
我還會(huì)對(duì)Casbin的ABAC進(jìn)一步的研究,各測(cè)試用例會(huì)發(fā)布到https://github.com/studyzy/abactest 有興趣的可以看看。
最后,關(guān)于Casbin采用的規(guī)則引擎為,https://github.com/Knetic/govaluate,編輯Matchers規(guī)則可以參考:https://github.com/Knetic/govaluate/blob/master/MANUAL.md
轉(zhuǎn)載于:https://www.cnblogs.com/studyzy/p/11380736.html
總結(jié)
以上是生活随笔為你收集整理的基于Casbin实现ABAC的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: 为什么好学生,学不好编程?
- 下一篇: Linux查看端口占用情况的命令
