Golang最强⼤的访问控制框架casbin全解析
Golang最强⼤的访问控制框架casbin全解析
Casbin是⼀个强⼤的、⾼效的开源访问控制框架,其权限管理机制⽀持多种访问控制模型。⽬前这个框架的⽣态已经发展的越来越好了。提供了各种语⾔的类库,⾃定义的权限模型语⾔,以及模型编辑器。在各种语⾔中,golang的⽀持还是最全的,所以我们就研究casbin的golang实现。
访问控制模型
控制访问模型有哪⼏种?我们需要先来了解下这个。
UGO(User, Group, Other)
这个是Linux中对于资源进⾏权限管理的访问模型。Linux中⼀切资源都是⽂件,每个⽂件都可以设置三种⾓⾊的访问权限(⽂件创建者,⽂件创建者所在组,其他⼈)。这种访问模型的缺点很明显,只能为⼀类⽤户设置权限,如果这类⽤户中有特殊的⼈,那么它⽆能为⼒了。
ACL(访问控制列表)
它的原理是,每个资源都配置有⼀个列表,这个列表记录哪些⽤户可以对这项资源进⾏CRUD操作。当系统试图访问这项资源的时候,会⾸先检查这个列表中是否有关于当前⽤户的访问权限,从⽽确定这个⽤户是否有权限访问当前资源。linux在UGO之外,也增加了这个功能。
setfacl -m user:yejianfeng:rw- ./test
[yejianfeng@ipd-itstool ~]$ getfacl test
# file: test
# owner: yejianfeng
# group: yejianfeng
user::rw-
user:yejianfeng:rw-
group::rw-
mask::rw-
other::r--
当我们使⽤getfacl和setfacl命令的时候我们就能对某个资源设置增加某个⼈,某个组的权限列表。操作系统会根据这个权限列表进⾏判断,当前⽤户是否有权限操作这个资源。
RBAC(基于⾓⾊的权限访问控制)
这个是很多业务系统最通⽤的权限访问控制系统。它的特点是在⽤户和具体权限之间增加了⼀个⾓⾊。就是先设置⼀个⾓⾊,⽐如管理员,然后将⽤户关联某个⾓⾊中,再将⾓⾊设置某个权限。⽤户和⾓⾊是多对多关系,⾓⾊和权限是多对多关系。所以⼀个⽤户是否有某个权限,根据⽤户属于哪些⾓⾊,再根据⾓⾊是否拥有某个权限来判断这个⽤户是否有某个权限。
RBAC的逻辑有更多的变种。
变种⼀:⾓⾊引⼊继承
⾓⾊引⼊了继承概念,那么继承的⾓⾊有了上下级或者等级关系。
变种⼆:⾓⾊引⼊了约束
⾓⾊引⼊了约束概念。约束概念有两种,
⼀种是静态职责分离:
a、互斥⾓⾊:同⼀个⽤户在两个互斥⾓⾊中只能选择⼀个
b、基数约束:⼀个⽤户拥有的⾓⾊是有限的,⼀个⾓⾊拥有的许可也是有限的
c、先决条件约束:⽤户想要获得⾼级⾓⾊,⾸先必须拥有低级⾓⾊
⼀种是动态职责分离:八月十五祝福语简短句子
可以动态的约束⽤户拥有的⾓⾊,如⼀个⽤户可以拥有两个⾓⾊,但是运⾏时只能激活⼀个⾓⾊。
变种三:既有⾓⾊约束,⼜有⾓⾊继承
就是前⾯两种⾓⾊变种的集合。
ABAC(基于属性的权限验证)
Attribute-based access control,这种权限验证模式是⽤属性来标记资源权限的。⽐如k8s中就⽤到这个权限验证⽅法。⽐如某个资源有pod属性,有命名空间属性,那么我设置的时候可以这样设置:
Bob 可以在命名空间 projectCaribou 中读取 pod:
{"apiVersion": "abac.authorization.kubernetes.io/v1beta1", "kind": "Policy", "spec": {"user": "bob", "namespace": "projectCaribou", "resource": "pods", "readonly": true}}
这个权限验证模型的好处就是扩展性好,⼀旦要增加某种权限,就可以直接增加某种属性。
DAC(⾃主访问控制)
在ACL的访问控制模式下,有个问题,能给资源增加访问控制的是谁,这⾥就有⼏种办法,⽐如增加⼀个super user,这个超级管理员来做统⼀的操作。还有⼀种办法,有某个权限的⽤户来负责给其他⽤户分配权限。这个就叫做⾃主访问控制。
⽐如我们常⽤的windows就是⽤这么⼀种⽅法。
很多的wiki权限也是这样的权限管理⽅式。
MAC(强制访问控制)
强制访问控制和DAC相反,它不将某些权限下放给⽤户,⽽是在更⾼维度(⽐如操作系统)上将所有的⽤户设置某些策略,这些策略是需要所有⽤户强制执⾏的。这种访问控制也是基于某些安全因素考虑。
casbin的基本使⽤
casbin使⽤配置⽂件来设置访问控制模型。我们可以通过casbin的模型编辑器来查看。
它有两个配置⽂件,f 和 policy.csv。其中 f 存储的是我们的访问控制模型,policy.csv 存储的是我们具体的⽤户权限配置。
权限本质上就是最终询问这么⼀个问题“某个⽤户,对某个资源,是否可以进⾏某种操作”。casbin的使⽤⾮常精炼。基本上就⽣成⼀个结构,Enforcer,构造这个结构的时候加载f 和 policy.csv。使⽤⽰例如下:
import "github/casbin/casbin/v2"
e, err := casbin.NewEnforcer("path/f", "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) // 查看alice是否对data1z这个资源有read权限
金融类大学排名if err != nil {
// handle err
}
if ok == true {
tenda路由器// permit alice to read data1
} else {
/
/ deny the request, show an error
}
当然,casbin 可以读取具体 policy 的时候不仅仅可以通过 csv ⽂件进⾏读取,也可以通过数据库进⾏读取。这样我们甚⾄可以写⼀个⽤户管理后台来配置不同的⽤户权限。f 也是可以从配置⽂件中获取,也可以从代码中获取,从代码中获取就可以扩展为先读取数据库,再代码加载。但是 f ⼀旦修改,对应的 policy 就需要进⾏同步修改,所以 model 在⼀个系统中不要进⾏频繁修改。
PML
casbin 的理论基础是这么⼀篇论⽂:。这篇论⽂是北⼤的三个学⽣⼀起发表的。要理解 casbin 的配置⽂件,就需要先看这篇论⽂。
论⽂的作者觉得现在云计算时代,权限管理系统是各种云⾮常重要的组成部分,但是各种权限管理模型在各个云⼚商,或者各种云时代的产品⼜都不⼀样。那么是否有⼀种权限模型来统⼀描述各种权限访问⽅式呢?如果有的化,这种权限模型⼜需要独⽴于各种语⾔⽽存在,才能被各种语⾔的云产品所通⽤。
于是论⽂就创造除了这么⼀种语⾔:PML(PERM modeling language)。其中的 PERM 指的是 Policy-Effect-Request-Matcher 。下⾯我们需要⼀⼀了解每⼀个概念。
Request
Request 代表的是请求,它的写法是
request ::= r : attributes
attributes ::= {attr1, attr2, attr3, ..}
⽐如我们写⼀⾏:
r = sub, obj, act
代表⼀个请求有三个标准的元素,请求主体,请求对象,请求操作。其中的sub, obj, act 可以是⾃⼰定义的,只要你在⼀个配置⽂件中定义的元素标识符⼀致就⾏。
梦见自己穿婚纱Policy
Policy 代表策略,它表⽰具体的权限定义的规则是什么。
它同样是形如 p = sub, obj, act 的表⽰⽅法,⽐如我们定义了 policy 的规则如此,那么我们在 policy.csv 中每⼀⾏定义的 policy_rule 就必须和这个属性⼀⼀对应。
Policy_Rule
在 policy.csv ⽂件中定义的策略就是 policy_rule。它和 Policy 是⼀⼀对应的。
⽐如 policy 为
p = sub, obj, act
我设置的⼀条 policy_rule 为
p, bob, data2, write
表⽰bob(p.sub = bob)可以对data2 (p.obj = data2)进⾏ write (p.act = write) 操作这个规则。
policy 默认的最后⼀个属性为决策结果,字段名eft,默认值为allow,即通过情况下,p.eft就设置为allow。
Matcher
有请求,有规则,那么请求是否匹配某个规则,则是matcher进⾏判断的。
matcher ::=< boolean expr > (variables, constants, stub functions)
variables ::= {r.attr1, r.attr2, .., p.attr1, p.attr2, ..}
constants ::= {const1, const2, const3, ..}
⽐如下⾯这个matcher :
m = r.sub == p.sub && r.obj == p.obj && r.act == p.act
表⽰当(r.sub == p.sub && r.obj == p.obj && r.act == p.act )的时候,返回true,否则返回false。
Effect
Effect ⽤来判断如果⼀个请求满⾜了规则,是否需要同意请求。它的规则⽐较复杂⼀些。
effect ::=< boolean expr > (effect term1, effect term2, ..)
effect term ::= quantifier, condition
quantif ier ::= some|any|max|min
condition ::=< expr > (variables, constants, stub functions)
variables ::= {r.attr1, r.attr2, .., p.attr1, p.attr2, ..}
constants ::= {const1, const2, const3, ..}
这⾥的 quantifier⼀般是some(论⽂中⽀持max和min),some表⽰括号中的表达式个数⼤于等于1就⾏。max/min表⽰括号中表达式的结果取最⼤/⼩的。(这⾥我不是很理解,不过好像casbin也没有实现min和max)
下⾯这个例⼦:
e = some(where (p.eft == allow))
这句话的意思就是将 request 和所有 policy ⽐对完之后,所有 policy 的策略结果(p.eft)为allow的个数 >=1,整个请求的策略就是为 true。⾃定义函数
⾃定义函数是在 matcher 中使⽤的。我们可以⾃⼰定义⼀个函数,然后注册进enforcer,在matcher中我们就可以使⽤了。
⽐如
func KeyMatch(key1 string, key2 string) bool {
i := strings.Index(key2, "*")
if i == -1 {
return key1 == key2
}
if len(key1) > i {
return key1[:i] == key2[:i]
}
return key1 == key2[:i]
}
func KeyMatchFunc(args ...interface{}) (interface{}, error) {
name1 := args[0].(string)
name2 := args[1].(string)
return (bool)(KeyMatch(name1, name2)), nil
}
e.AddFunction("my_func", KeyMatchFunc)
// 配置⽂件中就可以这样写了
[matchers]
m = r.sub == p.sub && my_func(r.obj, p.obj) && r.act == p.act
casbin中有⼀些⾃定义的函数:
关系
上⾯⼏个概念关系如下:
⼤概解释⼀下:
1 我们先定义属性,通⽤的⼀些属性如 subject, object, action。
2 定义的属性可以作为 Request 的属性,也可以作为 Policy的属性。
3 Policy_Rule 是 Policy 的具体规则。
4 使⽤定义的 Matcher 将 Request 和 Policy 进⾏匹配,这个匹配的过程可能使⽤到⾃定义函数。
好玩的iphone游戏5 所有的 Policy 匹配完成的结果,通过 Effect 规则得出最终是否可以访问的结果。
例⼦:ACL
理解上⾯的知识,我们应该能理解这个ACL的例⼦:
这个例⼦中定义了两个 Policy_Rule: (alice 对 data1 有 read 权限)和(bob 对 data2 有 write 权限)
当request (alice, data1, read)进来的时候,它匹配了其中⼀条规则,所以some 之后的最终结果为true。
例⼦:RESTFUL
RESTFUL接⼝使⽤URL和HTTP请求⽅法表⽰资源的增删改查,那么我们可以使⽤⾃定义函数来判断是否可以进⾏某个请求保养车
更多
这个论⽂还有⼀些其他的定义:
Has_Role
其实这个就是⼀个⾃定义函数的概念,只是它的参数是请求的主体和⾓⾊。这⾥引⼊了⼀个⾓⾊的概念。这个也是RBAC 权限模型所定义的。Has_Role 本质就是定义了⼀个 g 函数,这个 g ⽤于判断哪个⽤户是否属于哪个⾓⾊。这个 g 的函数也可以⽤配置写规则:
g = _, _
然后在 Policy 写规则:
g, alice, data2_admin
表⽰ alice 属于⾓⾊ data2_admin。
matcher 就可以写成这样:
m = g(r.sub, p.sub) && r.obj == p.obj && r.act == p.act
例⼦:RBAC
我们来看下下⾯这个RBAC的规则:
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论