【Yii Framework】 Role Based Access Control

给公司的项目做了一个内部运维站点,日久天长,发现功能越来越多,而且很多至关重要的东西都在上面,如果一个小白,胡乱点点,可能引发致命运维事故。于是乎,希望能做一个访问控制。

第一个想到的是Yii框架自己支持的RBAC系统,每个Yii App默认加载一个组件,就是authManager,可以应用一种基于角色的访问权限控制体系。以前虽然早就知道了这个,但是从来没用过,而且也从来没觉得好用过。光看了文章吹捧怎么科学了。

今天仔细研究了一下,官方站点有个实作模块,叫srbac,流传很广,就用了这个,希望顺便搞懂这东西。

srbac组件,是一个基于MySQL数据库存储访问权限的一个系统实现。一般的RBAC系统,将访问控制抽象出来了三个层次,一个是操作(Operation),一个是任务(Task),一个是角色(Role)。最原子的权限项是操作,整个授权不可分割。然后若干操作,可以组成一个任务;一个角色,在系统中可以完成若干任务;最后具体的用户跟角色绑定。

足够灵活了,也足够强大了,但是不够好用。至少srbac组件实现得实在是不怎么强大。首先,必须要有个用户表,而且用户表必须有主键。可以说,这是基于DB的RBAC系统必须要求的,但是比如我们内部系统,就有自己的用户鉴权体系,也有自己的帐号体系,是公司的OA系统直接提供的,这就蛋疼了,我不得不自己实现了一个CModel,里面封装了srbac要用到的几个方法,并跟OA体系对接起来。

然后,发现srbac系统中,并没有默认角色,默认权限这种概念,如果我需要实现访问控制,就要对全量的操作进行赋值。其实我们内部系统,就只有几种,一个是系统配置,一个是系统监控,一个是数据查看。我需要的权限也就几种,极少数人可以系统配置,所有的开发可以系统监控,所有的开发和产品可以查看数据,除此以外的所有人什么都不能干。这个srbac系统就显得极其累了,确实可以配置出来我需要的权限体系,但是好累。

然后再说这个东西怎么进行权限控制。在所有需要权限判断的地方,都要加一个语句调用:

1
2
3
4
5

if (Yii::app()->user->checkAccess('changeStaticVersion')) {
//here to put code to change static files' version
}

这是何其蛋疼,现在系统一个几十个功能了,难道要我所有的都加一遍么?好吧,还可以用filter来实现这个。但是几十个功能啊,难道要我所有的功能都手动命名一遍么?累得蛋疼啊……

于是乎,我已经想放弃了。童话是美好的,但是现实不美好,我真的没找到什么简单的解决方案。直到最后。

我想要这么一种系统。第一,基于Controller Action的路由规则来,某个Controller,某个Action,什么角色可以访问。然后要有默认角色,默认权限,不配置的,全部都是默认角色和默认权限。这样我只要把系统里需要管的管起来就行了。说起来简单,自己实现就行了。为啥就不能有现成的呢?当然我这种设计,弊端也是相当多的,首先就是权限的粒度设计不合理,因为一个Action里面明显可以做很多事情啊,如果有权限交叠,就会没法handle了。好吧,但是在我的场景里,我就希望一个这种简简单单的东西……