数据权限设计思考目前有关用户权限采用的比较多的都是基于RBAC模型
目前有关用户权限采用的比较多的都是基于RBAC模型,即
通过对角色权限的定义完成对用户权限的限制。有关功能权限部分想必都比较清楚,就是将系统的功能模块划分清楚,并赋予不同角色的访问权限,这样在用户访问某个功能模块之前进行权限校验即可。但是有关数据权限部分却一直比较模糊。
在如下这篇文章中给出一个权限模型,里面提到了数据权限的建模。
http://blog.csdn.net/fly_cloud/archive/2006/08/09/1041807.aspx
这个模型中有关数据权限也是对角色进行权限限定。模型中定义了几个概念:
资源:用户将要访问的数据对象(如用户)
数据对象类型:对用户将要访问的数据对象的限定类型(如部门)
资源数据对象类型:上面两个概念关联产生的,即
用户要访问什么类型的数据对象(如××部门的用户,但是此时的××是通用的,只有将数据对象类型具体化之后××才会出现)。
将上面的资源数据对象类型实例化(即××具体化)之后就形成了一条
数据对象访问规则,将这条规则附加给某个角色就完成了对角色数据访问权限的限定。这个模型定义是很清楚的,但是如何具体实现,其实是一个比较复杂的问题。
一个比较直观的想法就是在业务层之上加一个数据权限校验层。
上面定义的
数据对象类型其实就是用户访问的数据对象的属性,因此
在校验的时候确定相关数据对象的属性是否满足用户数据权限规则即可,对于增删改就是操作之前校验,对于查询就需要对查询结果过滤。当然为了整个实现的简单需要确保系统中的所有数据对象Class都是从一个Class中继承而来限制。这一想法实现起来比较简单,但是有一个限制和一个性能忧虑。
限制就是为了保证规则校验的进行,必须使得所有数据对象都应当具有权限规则定义的相应属性,如果规则定义的属性发生变化,势必需要所有数据对象的生成方法发生变化。
性能忧虑就是对查询结果的过滤,其实在一般的MIS系统中多数情况是进行查询,但是如果依照这种方法进行结果过滤的话,可能会存在性能的问题。
因此,这一想法具有紧耦合和性能问题。
另外一个想法依然无法避免紧耦合,但是可以避免性能问题。然而在逻辑上就没有上面那个直观了。这一想法就是
将数据权限规则转成SQL语句,嵌入到数据访问层中去。
因为资源必定会对应到某一个数据表,而数据对象类型也会对应的到某个数据表的某个属性列,因此完全可以依据数据权限规则动态生成SQL语句。数据权限规则可以如下定义:【资源数据对象类型 关系符 右值】,右值可以分为静态和动态两种:静态就是一个具体的值;动态就是用户的某个属性,这只有在与用户关联上之后才能确定。但是由于
一个角色可以有多条数据权限规则,那么他们之后可以是与和或的关系,多个规则之间可能存在冲突,必须进行避免,如:当规则之间是与关系时,如果资源数据对象类型和关系符都相同时,就有可能冲突。具体的说就是要限制角色R只能访问A部门的用户且只能访问B部门的用户,这样子势必是相互冲突的。
在数据访问层调用一个统一的SQL生成方法,传入两个参数:不加限定是要访问的数据表名和角色数据权限规则集(此时的规则集中应当已经具有准确的右值,即如果是动态的也已经根据用户属性赋值了)。方法是:依次判断规则集中的规则是否有要访问的数据表名,如果有就生成SQL语句的FROM子句和WHERE子句,最终语句规则集关系符(AND | OR)生成FROM子句和WHERE子句返回。
数据访问层获得权限校验产生的FROM子句和WHERE子句嵌入到数据访问方法中去,这样就将数据访问和权限校验结合在一起了。明显是紧耦合,但是规避了性能问题。
因此,上面两个想法各有个的优势,但是同样都有一定的问题,是不是有更好的办法?继续思考中……
转载自http://peng4602.iteye.com/blog/680657