Ralasafe开源有段时间了,大约有2个月了。根据社区的反馈,我打算围绕Ralasafe最佳实践,书写一系列BLOG。
大体内容有:
1, 登录控制: 哪些页面需要登录后才能访问,登录用户名、密码验证,登录转向页面;
2, URL权限控制:哪些页面访问需要进行角色权限验证,怎样验证最简单有效,如何处理验证失败情况;
3, 数据级权限管理方案探讨:选择中间件呢还是框架?
4, Ralasafe体系结构: 用户怎么读取,用户有哪些字段,怎样与应用基础;
5, 数据级查询权限管理: 如何给不同的人分配不同的查询数据权限,返回where条件呢,还是直接返回结果集?
6, 数据级决策权限管理: 如何给不同的人分配不同的数据操作权限,当用户不具备权限怎么办?
7, 其他细小的权限控制: 如下拉框显示内容;按钮、链接是否显示,图片是否显示等。
-------------------------------------------- ------- --------------------------------
数据级权限管理需求
数据级权限管理需求主要有:
1,支持不同用户查询到数据是不同的;
2,支持数据库行级、列级查询;
3,支持分页查询——包括2个方面:a,分页查出数据;b,能告知总数据条数是多少;
4,支持自定义条件(比如:张三在自己的查询权限范围内,查询50w以上的订单)。
理论分析
能够将数据级权限,与业务分离出来——是多年来开发人员追求的目标。一旦遇到疑难杂症,马上会让人联想到高难度的API编程,或者绚丽的XML配置。
不过,我今天的分析,会极其简单。不过我强烈建议大家看下去。如果对该方案有所怀疑,请使用你的应用案例进行试验。我当时不敢确认的时候,就是这么做的。
(当初,我提出该方案的时候,我们团队认为该方案过于简单,不可行。我坚持让他们实现该方案。等产品做出来后,他们略有所悟,认为该方案可行。当,我让他们做demo的时候,将该方案运用于案例的时候,他们拍腿叫道:超级太棒了!我希望你也有该感受)
分类思想的提出
首先,我们思考这个问题:为什么我们在程序里面使用了if/else?为什么数据级权限难以处理?
原因就是:1,有很多种情况;2,我们需要针对不同的人、不同的情况做不同的权限逻辑。比如:
-
if
是总公司用户? then 查询所有订单;
-
else
if
是分公司用户? then 查询本分公司(${用户的公司})及下属子公司订单;
-
else
-
then 查询本子公司订单(${用户的公司})
if 是总公司用户? then 查询所有订单;
else if 是分公司用户? then 查询本分公司(${用户的公司})及下属子公司订单;
else // 是子公司用户了
then 查询本子公司订单(${用户的公司})
在RBAC模型里面有用户群组概念,也有不少开发人员将用户群组引入数据级权限管理领域。群组很好的将用户归组,但不足之处是要事先将用户归入组内。比如,在将张三指定到“总公司用户组”之前,他不属于该用户组,即便张三的机构属性显示他属于总公司。
我们对群组进行稍微改造:使用规则来定义群组,满足该规则的用户,我们则
认为该用户属于该群组。传统编程里面的if/else判断条件,基本都可以使用规则或者规则表达式组来描述。此时,张三的机构属性显示是总公司,那么他就
属于总公司用户组;如果他的机构属性是某个分公司,那么他就属于分公司用户组了。无需进行额外操作(指定、重新指派等,一切都是动态智能的)。
OK,至此,我们提出了使用规则描述的“用户分类”。该规则应该能读取用户信息、上下文信息、数据查询等,并进行相关运算(比较、集合运算等)
至此,我们可以基于用户要分类,为每个用户分类分配一个查询。(该查询可以接受相关参数,比如用户参数、上下文参数等)
那么上述例子,使用分类思想,可以这么解决:
用户分类:总公司用户类 —— 查询:查询所有订单
用户分类:分公司用户类 —— 查询:查询本分公司及下属子公司订单;
用户分类:子公司用户类 —— 查询:查询本子公司订单。
与功能权限结合
我认为功能权限与数据权限分开非常合适。功能权限由企业IT管理员维护;数据权限由软件开发商维护。有人会说这样不好,比如这个案例怎么处理:
普通审查员可以审查50w财务数据;中级审查员审查50w~500w的财务数据。这个50w、500w,企业需要自行维护。
OK,我认为这50w、500w应该称为“权限策略数据”,可以保存到数据库里面,做为基础数据或者数据字典由企业通过界面自行维护。而软件开发商,开发的“数据级权限”策略读取这些数据。(当然,你可以缓存。。。。)
Ralasafe方案
怎样实现数据级查询权限
为了理解本节内容,建议下载ralasafe demo应用,对照图形界面,更容易理解些。
Ralasafe使用管理界面来定制用户分类、定制数据查询。为了确保定制无误,Ralasafe支持在线测试。比如定制用户分类后,可以选择一个用户进行测试。数据查询等都是可以在线测试的。
定制完毕后,将用户分类和数据查询配对,赋给特点权限。一个权限,可以赋多个(用户分类——数据查询)配对。和前面的理论分析一样。
具体定制,怎样配对,可以参考文档,配有图片,在此不做多说。定制用户分类,定制数据查询,给权限授权策略(即配对)。
怎样与应用结合
Ralasafe提供org.ralasafe.Ralasafe和org.ralasafe.WebRalasafe两个接口类。里面的query方法对应数据级查询权限。在应用系统相应的地方,调用该方法即可。我建议在系统的控制层调用,即:servlet或者action。
ralasafe demo例子,EmployeServlet就是这么调用的:(demo演示员工查询,不是订单查询)
-
-
Collection employees = WebRalasafe.query(req, Privilege.QUERY_EMPLOYEE);
-
-
req.setAttribute("employees", employees);
// 通过Ralasafe接口获取当前用户被授权查看的员工
Collection employees = WebRalasafe.query(req, Privilege.QUERY_EMPLOYEE);
// 将数据放入request,供前台展示
req.setAttribute("employees", employees);
OK,就这么简单。需要编程的工作量非常非常少,达到了极致。世界从此清净了。
(WebRalasafe.query方法接受req<HttpRequest>参数,从这里读取User。Ralasafe.query方法则直接传入User,可供非web类应用调用)
系统结构
Ralasafe由权限引擎和管理界面组成。权限引擎解析权限策略;管理界面生成、维护权限策略。如图示:
注:ralasafe团队博客在javaeye/baidu/blogjava等空间,同步发布。ralasafe官方网站:
http://www.ralasafe.org/zh