2009年6月18日
-------------------------------------------- 总大纲 ---------------------------------
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 查询本子公司订单(${用户的公司})
在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演示员工查询,不是订单查询)
// 通过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
posted @
2010-09-08 21:38 细粒度权限管理 阅读(4820) |
评论 (1) |
编辑 收藏
-------------------------------------------- 总大纲 ---------------------------------
Ralasafe开源有段时间了,大约有2个月了。根据社区的反馈,我打算围绕Ralasafe最佳实践,书写一系列BLOG。
大体内容有:
1, 登录控制: 哪些页面需要登录后才能访问,登录用户名、密码验证,登录转向页面;
2, URL权限控制:哪些页面访问需要进行角色权限验证,怎样验证最简单有效,如何处理验证失败情况;
3, 数据级权限管理方案探讨:选择中间件呢还是框架?
4, Ralasafe体系结构: 用户怎么读取,用户有哪些字段,怎样与应用基础;
5, 数据级查询权限管理: 如何给不同的人分配不同的查询数据权限,返回where条件呢,还是直接返回结果集?
6, 数据级决策权限管理: 如何给不同的人分配不同的数据操作权限,当用户不具备权限怎么办?
7, 其他细小的权限控制: 如下拉框显示内容;按钮、链接是否显示,图片是否显示等。
-------------------------------------------- ------- --------------------------------
数据级权限
数据级权限,无外乎这些类型:
1,数据库行列级:比如领导查询数据范围和普通员工查询的数据范围不同,客户经理能够查询客户联系方式字段,而其他人不能查看客户联系方式字段。
2,字段内容控制:比如普通审查员审查50w以下财务数据,刚入职客户经理只能将客户级别调整不能超过3级。
从用户与数据的交互方向可以分为2大类:
1,从系统获取数据(查询);
2,向系统提交数据之前的判断。
现实困惑
这种权限与业务紧密耦合,很难找到通用方法。绝大部分系统仍然采用if/else来编程,而且这种逻辑分散到系统的各个环节,甚至还会在系统多处出现重复判断。
也有不少网友尝试5表模型等,试图通过数据模型构造好的ACCESS CONTROL LIST来控制。这种构造ENTRY模式,当数据量小的时候,是可行的,维护工作量也不大。当数据量大的时候,显然不能奏效。甚至无法运行,维护工作量非常大。
主要表现在:
1,where 语句里面的in(..., ..., ..., ..., ...) 子条件过长,或者使用in (select ... from ACL_ENTRY where ... )性能也是非常低下的;
2,当删除某用户的时候,需要在ACL_ENTRY表里面,删除相关记录;
3,当删除某业务数据的时候,也需要在ACL_ENTRY表里面,删除掉相关记录;
4,数据量大,ACL_ENTRY数据量承几何级增长。
也有企业尝试使用规则引擎来解决。这是非常好的尝试,提升了系统开发效率、组件复用率。
主要表现在:
1,首先,主动的实践了一项最佳项目实践:权限与业务松耦合。
2,通过松耦合,大幅优化了系统结构。
3,进一步提高了组件复用率。
只是,规则引擎毕竟不是专业于权限管理领域,对于复杂需求,或者有些需求实现起来还是很别扭。看起来像if/else的规则表达罢了。
Ralasafe和IBM、Oracle商业产品一样,都使用规则进行描述。大家的区别在于:谁满足需求更多、更容易了。
框架or中间件
框架的好处,显然是有个体系结构,团队遵循该方式进行开发、组装即可。提供了一种标准和开发模式。
中间件的好处,显然是提供了自由,而且易于结合、易于分工。提供了一种服务方式。
我本人希望自由,所以讨厌框架,偏爱中间件。但我对选用中间件、框架的选择标准是非常中肯的,供大家参考。
在系统结构分层的场景,适合使用框架。
在系统功能分离的场景,适合使用中间件。
那么具体到权限管理领域,显然是功能分离,中间件更合适。这么做,还将不给原有系统、新开发系统的既定框架造成冲突。一个系统里面使用多个框架,是非常痛苦的事情。殊不知在SSH的海洋里面,有多少人将N多时间“Kill”在沙滩上?!
Ralasafe体系结构及应用集成
Ralasafe是中间件,采用服务模型。在业务需要的地方,调用Ralasafe接口,或者将Ralasafe接口向LOG4J那样wrap到你的aspect里面去。
Ralasafe按照权限的方向,提供2种数据级权限管理服务,也正好对应2个接口:
1,从系统获取数据, Ralasafe.query( int privilegeId, User user, CustomizedWhere where, int fromIndex, int size );
2,向系统提交数据之前的判断,Ralasafe.permit( int privilegeId, User user, Object businessData);
Ralasafe还针对web应用,提供了WebRalasafe。
接口非常简单,在接口层只要告知Ralasafe:当前这个是谁,他/她想干什么。
权限逻辑,全部在Ralasafe图形化管理界面,点击鼠标完成配置,并进行在线测试。无需编程。
所以,使用Ralasafe编程工作量非常少。也给不少开发人员造成“不知道怎样与应用集成”的错觉。
Ralasafe的用户怎么来
Ralasafe并不会给你的应用系统“假定”有哪些字段。你的应用系统用户可以由任意字段,通过XML文件安装到Ralasafe即可。该XML文件,主要指明:用户存在那张表(也可以是视图,这样可以从多张表关联读取数据。比如ralasafe-demo,就关联到company表读取了companyLevel和companyName字段); 哪些字段是唯一字段; 哪些字段是主键;各字段对应类型。
然后,在所有权限规则里面,可以读取这些用户字段。比如ralasafe-demo应用(下载地址:
http://www.ralasafe.org/zh/download/download.jsp ) 用户含有companyLevel字段,在定制“总公司”用户分类的时候,就将该用户companyLevel字段与总公司级别“1”进行比较。
(下期真正开始探讨数据级权限管理实现了)
注:ralasafe团队博客在javaeye/baidu/blogjava等空间,同步发布。ralasafe官方网站:http://www.ralasafe.org/zh
posted @
2010-09-06 22:58 细粒度权限管理 阅读(2055) |
评论 (0) |
编辑 收藏
-------------------------------------------- 总大纲 ---------------------------------
Ralasafe开源有段时间了,大约有2个月了。根据社区的反馈,我打算围绕Ralasafe最佳实践,书写一系列BLOG。
大体内容有:
1, 登录控制: 哪些页面需要登录后才能访问,登录用户名、密码验证,登录转向页面;
2, URL权限控制:哪些页面访问需要进行角色权限验证,怎样验证最简单有效,如何处理验证失败情况;
3, 数据级权限管理方案探讨:选择中间件呢还是框架?
4, Ralasafe体系结构: 用户怎么读取,用户有哪些字段,怎样与应用基础;
5, 数据级查询权限管理: 如何给不同的人分配不同的查询数据权限,返回where条件呢,还是直接返回结果集?
6, 数据级决策权限管理: 如何给不同的人分配不同的数据操作权限,当用户不具备权限怎么办?
7, 其他细小的权限控制: 如下拉框显示内容;按钮、链接是否显示,图片是否显示等。
-------------------------------------------- ------- --------------------------------
今天说的URL权限控制,内容主要有:URL权限控制,当用户访问某URL时,进行角色权限验证。如果有相应权限,则允许其正常访问;否则,转到拒绝页面。
我们依然通过一个Filter来实现,这样就无需在代码中增加权限判断,也无需套用任何框架。对于整个权限管理系统来说,本节内容也非常简单。
理论分析
当软件实施人员进行系统实施的时候,会将一些访问菜单定义为权限。然后定义角色,让角色拥有权限。然后再将权限赋给用户。
所以,当用户请求某个URL的时候,要不该URL需要权限验证,要不就是不需要权限验证。
检验标准就是:看权限表里面有没有该URL。检验的时候,唯一需要注意的是:URL参数,比如employeeManage?op=add。
数据库模型
权限表:id<int>,name<varchar>,url<varchar>,description<varchar> | pk(id)
角色表:id<int>,name<varchar>,description<varchar> | pk(id)
角色-权限关系表:roleId<int>,privilegeId<int> | pk(roleId,privilegeId)
用户-角色关系表:userId<int>(根据你系统的情况,也可能是varchar等),roleId<int> | pk(userId,roleId)
Ralasafe方案
Ralasafe权限管理中间件(
下载地址),既可以管理和控制功能级权限,也可以管理和控制数据级权限。开发者还可以根据需求,只选择功能级控制,或者只选择数据级控制。
当
安装好用户元数据的时候,Ralasafe自动创建所有权限表。相关权限数据,都由Ralasafe界面进行管理(即录入)。
Ralasafe的管理界面,在功能权限方面可以做到:
1,管理权限界面;
2,管理角色界面,并给角色赋权限;
3,给用户分配角色界面。这里还需要注意:不同用户管理可以给不同范围的用户分配角色。比如:总公司的管理员可以给所有人分配角色;分公司管理员可以给本分公司及下属子公司用户分配角色。
Ralasafe将最后一点视为数据级权限。详见:
http://www.ralasafe.org/zh/guide/reference/safe.html#ralasafe 和
http://www.ralasafe.org/jforum/posts/list/11.page
将
org.ralasafe.webFilter.UrlAclFilter配置到web.xml即可,而且配置工作量极其少。
<filter>
<filter-name>ralasafe/UrlAclFilter</filter-name>
<filter-class>org.ralasafe.webFilter.UrlAclFilter</filter-class>
<init-param>
<param-name>loginPage</param-name>
<param-value>/ralasafe/demo/login.jsp</param-value>
</init-param>
<init-param>
<param-name>denyPage</param-name>
<param-value>/ralasafe/demo/noPrivilege.jsp</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>ralasafe/UrlAclFilter</filter-name>
<url-pattern>/ralasafe/demo/*</url-pattern>
</filter-mapping>
该Filter具有这些功能:
1,在用户具有权限的时候,正常访问;
2,在用户不具有权限的时候,转到拒绝页面;
3,如果用户没用登录,转到登录页面,让用户先登录。
其他
这里我简单说说spring security。
spring security在控制功能权限的时候,还会帮助开发人员控制Dao/Service等组件。我个人认为这种控制是多余的。
因为,功能权限控制应该站在最终用户角度进行考虑。Dao/Service等编程开发级的组件,并不是最终用户关心的事情。所以无需进行功能权限控制。
另外,大家在使用spring security,我建议将功能级权限控制放在数据库里面,而不是annotation到java code里面。因为annotation到java code里面,最终用户就不能控制了。
注:ralasafe团队博客在javaeye/baidu/blogjava等空间,同步发布。ralasafe官方网站:
http://www.ralasafe.org/zh
posted @
2010-09-02 21:55 细粒度权限管理 阅读(2578) |
评论 (0) |
编辑 收藏
原文:
http://www.ralasafe.org/jforum/posts/list/66.page
Ralasafe自从2010年6月23日开源以来,得到广大网友的支持和鼓励,在此非常感谢。Ralasafe团队也通过网站、论坛、博客、Email、QQ等各种方式与社区互动,形成交流。根据这段时间的社区维护情况,我们制定如下社区维护原则。
我们欢迎这样的人,乐于回答他们的问题:
1,说话友好,平等切磋的人;
2,勤于学习,而不论技术高低,不论新手老手。即便你是新手,但只要你肯予学习,不断交流,我们乐于提供帮助;
3,带有个人偏见,但言之有物的人。
我们不欢迎这样的人,也不想回答他们的问题:
1,出言不逊,带有蔑视或者侮辱性语言的人;
2,懒惰的人,尤其是没有看文档,没有对Ralasafe-demo进行揣摩,没有进行基本学习的人;(文档没有看懂的人例外,确实我们可能撰写方式有问题,个人理解力有差距等)
3,带有个人偏见,且言之无物的人。
Ralasafe团队将继续保持开源,并致力于社区维护工作。对于新手,只要乐于学习,我们甚至会对学习难点,免费提供QQ远程协助。
posted @
2010-09-02 15:04 细粒度权限管理 阅读(447) |
评论 (0) |
编辑 收藏
摘要: Ralasafe是基于MIT协议开源的,数据级权限管理中间件。开源有2个月了。根据社区的反馈,我围绕Ralasafe最佳实践,书写一系列BLOG。今天说的登录控制,内容主要有:哪些页面需要登录控制、登录验证逻辑、登录后页面转向哪里,以及权限菜单等问题。虽然本系列讲解权限管理,尤其是数据级权限管理。但严格意义来说,登录控制,并不属于权限管理内容。它属于用户身份认证内容。权限基本都与用户相关,用户首先就涉及到用户名密码验证。所以我们从这里开始说起。
阅读全文
posted @
2010-09-01 19:41 细粒度权限管理 阅读(3703) |
评论 (2) |
编辑 收藏
摘要: 很多系统对于黑客不堪一击。请看这样的示例:
1. 前台展现客户能查看的客户数据,而且用户能删除的客户数据,就是前台展现出来的数据;
2. 当用户选择某个用户,点击删除按钮,后台执行删除操作。
比如,请求后台删除的url是:http://www.test.com/crm/customer.do?id=3
假设,id=13的客户在前台不显示(因为当前用户没有对该客户数据有删除权限),但用户输入http://www.test.com/crm/customer.do?id=13 显然id=13的客户将被删除掉。
有开发者建议采用id值不要使用自增长型,而改用其他型,比如hashcode等。这也不大合适,可以使用爬虫轻松地将漏洞爬出来。
显然,仅仅通过界面层次控制数据级权限是不够的。
阅读全文
posted @
2009-06-23 09:55 细粒度权限管理 阅读(3463) |
评论 (3) |
编辑 收藏
今天是夏至,白天是一年中最长的。好好努力。此文激烈自己和同样在努力的朋友们。
posted @
2009-06-21 21:52 细粒度权限管理 阅读(381) |
评论 (1) |
编辑 收藏
摘要: 上一章讲解通过设计器,设计出数据查询,并在线测试。本章讲解如何快速定制数据查询,如果将业务代码中的if else逻辑判断去掉,如何将这种细粒度的权限集成到业务系统。
阅读全文
posted @
2009-06-21 21:47 细粒度权限管理 阅读(2106) |
评论 (0) |
编辑 收藏
摘要: 通过基于角色访问控制,我们可以控制哪些人具有某种权限。比如总公司员工柴其贵、分公司员工李朵朵和营业部员工贾志宏,三个人都具有访问“查询员工”页面权限。但,由于他们三人所在公司级别不同(总公司、分公司和营业部),进入查询员工页面,系统展示出来的员工数据应该是不同的。
为此,很多系统代码里面充满了if else逻辑判断,造成业务与权限耦合。有更好的办法去除这种耦合吗?
阅读全文
posted @
2009-06-19 11:52 细粒度权限管理 阅读(2353) |
评论 (2) |
编辑 收藏
摘要: 本章详细讲解用户角色权限关系。这也就是RBCA(Role Based Access Control,基于角色的访问控制)。基于角色控制模型已经深入人心,关系并不复杂,广泛运用于各个系统。通过给用户赋予角色、角色拥有权限的模式,达到控制用户具有权限的目的。同时,还复用了角色,这样可以让多个相同职务(或职能)的人拥有同样的角色。RBCA模型怎么建立呢?又有哪些局限性。
阅读全文
posted @
2009-06-18 10:57 细粒度权限管理 阅读(3712) |
评论 (2) |
编辑 收藏