RBAC 和 Casbin 的关系?
RBAC
大家都知道是一种访问控制模型,Casbin
实现了这个模型,并且还实现了其他很多种访问控制模型,如ABAC
模型。
Casbin 解决了什么问题?
无需自己从零开始做一套访问控制系统,比如为用户添加角色,为角色添加权限等等接口都已经实现了。这套框架被多种语言实现,并且有多种存储适配器。
Casbin 中的概念和 RBAC 的对应关系?
RBAC
中的概念很简单,很容易理解,这里再赘述一下:角色,用户,权限。这三者组合来判断是否能形成对某一资源拥有访问资格。
Casbin
中的概念虽然比较多(因为这一套框架还要兼容其他的访问控制模型),但是仔细看下去,也是比较容易理解的。
以张三读取文章接口为例
RBAC
的鉴权流程:先看张三的所有身份,再看这些身份下是否拥有读取文章接口的权限。
Casbin
的鉴权流程:将张三读取文章接口,抽取三个要素。
第一,操作对象(sub
):张三
第二,动作(act
):读取
第三,资源(obj
):文章接口
将这三要素组合成一组请求r
,拿着这组请求和已有的策略p
,去某个列表里按某种匹配规则m
进行匹配,匹配后的结果传入到影响
e
中,看是否通过。(别急,下面有解释)。
以上涉及到了几个 Casbin 的重要概念,sub
,act
,obj
,r
,p
,m
,e
。其中sub
可以是单用户,也可以是角色。其中p
,m
,e
,相对于RBAC
模型中我们可能很少遇到。
下面将对以上概念进行解释。
r:请求,由上述三要素组成,格式与
p
一致。可以理解为入口函数。p:策略=
{sub,obj,act}
,会有一个策略列表(可以简单地理解为等同于 RBAC 中角色和权限的关系表)。通常我们如果仅用RBAC
的话,理解到这里就可以了,后面其实还可以有一个参数,可以简单地理解为禁用(即该操作对象不能操作此资源),黑名单,表示这一组策略被拉黑或者通过,默认为通过。m:
m
解决的是p
和r
如何进行匹配的问题,是匹配规则,仅返回是否匹配中 。可以理解为如何找到策略列表中对应的规则。
比如在此项中,我们可以加入超级管理员的角色的匹配规则,即使没有匹配中常规规则,但如果你是超级管理员的话,也默认为匹配中了。e:影响。仅做最终对匹配结果后的处理,即最终由这里返回是否通过。只可能有四种(官网有)。可以理解为最后的判断规则。为什么会有这个呢?按道理来说仅有
m
就够了啊?
实际上还是因为上面说过的原因,因为Casbin
做的不仅是简单RBAC
,在其他或者更高阶的RBAC
中,可能会出现有一条策略匹配中了,同时也还匹配上了另外一条策略,但是后一条策略表达的是该用户不能使用此资源,问题就来了,一条允许,一条不允许,那到底是通不通过呢?这时e
就发挥了作用,你既可以在此项设定所有策略都通过即为通过,也可以设定为有一条通过即为通过。
没有涉及到的概念:角色域。g=用户,角色。这个是用于多租户(多商户)模型的权限控制系统,这里不表。
其他概念和我的经验?
先简单了解一下,做的过程中大致流程和概念及要注意的点,这些清楚后我们就只是调用接口的事了。
两个文件
Casbin 官网中可以看到,初始化时,涉及到了两个文件,一个是模型配置文件model.conf
,一个是策略文件。
模型文件中,可以定制上述概念的各种组合,比如说m
中的超级管理员,e
中的到底通不通过问题,别担心,这个或许真的不用存到数据库中,一般定下来就不会动了的。
策略文件,我们就还是算了吧,存储到数据库中,更方便我们管理,Casbin
中有各种存储适配器,我使用的是grom
的适配器。
注意点
- 在官网中,
Casbin
明确指出,用户表和角色表,应当由项目自己管理,Casbin
只做权限控制。 - 当我们使用
grom
适配器时,初始化Casbin
的时候,会默认创建一张表casbin_rules
,这里面可以存储用户和角色的关系,角色和权限的关系。(这里只说使用Casbin
的RBAC
模型) - 上两点可以得知,用户表,角色表,权限表,我们无论从业务角度还是
Casbin
的限制,都应该我们自己来创建管理。 - 官方文档中,会存在一些错误,有时候我们还是需要读一下
Casbin
和适配器的源码,究竟该如何使用这些接口,甚至说看这些接口有没有。一定要注意Casbin
和适配器的版本,不然可能跟文档对不上。 Casbin
为了性能考虑,会将一些数据载入内存中。所以,当项目重启时,一定要记得将casbin_rules
那张表载入到内存中去,即初始化Casbin
时,调用LoadPolicy()
。- 在我们删除或修改用户,角色,权限时,记得想一下,
casbin_rules
那张表需不需要动呢?如果要动,可以去官网文档中找到对应接口。 - 我的实践,在
casbin_rules
中,角色和用户,我均只存储角色 id 和用户 id ,角色和权限的对应关系中,角色我存 id,权限通常是路由地址,因为检查权限通常是读多写少,这样做的好处是请求来时可以直接通过路由地址和用户 id 检验权限,不用自己再到数据库中查到路由地址 id 后再去查权限。
具体代码什么的很简单,就是纯调用接口。在这里我就不贴出来了,相信看到这里,再结合看一下Casbin
文档,大家都能写出来。以上是我最近学习使用 Casbin
的经验教训和总结,希望对大家有帮助。