锁定老帖子 主题:Spring Security优劣之我见
该帖已经被评为良好帖
|
|
---|---|
作者 | 正文 |
发表时间:2009-04-10
<security:authorize ifAllGranted="ROLE_admin">xx</security:authorize>
这种做法和添加权限码是一样的,我的想法是,因为在分配操作权限的时候,已经分配了一次,在那里可以指定某个操作的权限,维护一个操作的权限树,然后给该角色分配。可以用二进制的与来判断该角色是否具有该权限。但是有一点就是这个树很难包容变化,稍微变化了可能就乱套了。 树的结构: ---公告 ----新增 ----修改 ----删除 ---投诉 ----新增 ----修改 ----删除 对于公告权限表达是三位数字 001 表示有删除功能 以上都类似 |
|
返回顶楼 | |
发表时间:2009-04-10
发现了Apache也有一个权限的安全框架,不过还在Incubator中。框架名字叫Ki
一个介绍其的PPT : http://cwiki.apache.org/KI/articles.data/Ki-DevNexus-2009.pdf MS这个框架也不错。 不知道有没有研究过这个东东啊? |
|
返回顶楼 | |
发表时间:2009-04-10
metadmin 写道 downpour 写道 metadmin 写道 我博客里面有演示:
http://metadmin.iteye.com/blog/359533 我简单看了一下,你的数据权限那块,我没有能够看到相应的代码,和step by step的操作,我想知道如何应用到具体的项目中去。 演示例子:(构建项目,编写业务代码等) http://www.metadmin.com/demo1/index.html 权限逻辑定制过程:(FLASH, 持续时间约8分钟,全屏观看效果更好一些) http://www.metadmin.com/download/showEmployees.html 你没有明白我的意思。你给我看的,是你做的产品。我并不关心你做了什么产品,我所关心的是我如何将你的产品运用到我自己的项目中去,从而实现数据访问权限的控制。 请解释一下。 |
|
返回顶楼 | |
发表时间:2009-04-11
metadmin 写道
缺点我个人认为Spring Security存在以下几个硬伤: <!--[if !supportLists]-->1. <!--[endif]-->角色被“编码”到配置文件和源文件,这样最终用户就不能创建角色了。但最终用户期望自己来控制角色。因为在项目实施过程中,客户可能并不能确定有哪些角色,以及角色怎么分配给系统用户。角色大多需要等到系统上线后,才能确定。这些编码有: <!--[if !supportLists]-->a) <!--[endif]-->url的权限控制,<intercept-url pattern="/**" access="ROLE_USER" />; <!--[if !supportLists]-->b) <!--[endif]-->java方法的权限控制,@Secured("IS_AUTHENTICATED_ANONYMOUSLY"); <!--[if !supportLists]-->c) <!--[endif]-->java方法的权限控制,<protect method="set*" access="ROLE_ADMIN" />; <!--[if !supportLists]-->2. <!--[endif]-->RBCA这种被广泛运用的模型,没有在Spring Security体现出来; <!--[if !supportLists]-->3. <!--[endif]-->Spring Security没有提供好的细粒度(数据级)权限方案,提供的缺省实现维护工作量大,在大数据量情况下,几乎不可用; <!--[if !supportLists]-->4. <!--[endif]-->Spring Security对于用户、角色、权限之间的关系,没有提供任何一种维护界面。不过从Spring Security角度看,确实没有必要有界面。角色创建、角色和权限直接的关系,都被“编码”到配置文件和源文件了; <!--[if !supportLists]-->5. <!--[endif]-->Spring Security学习难度大,配置文件还是很多。我承认有很多高手,但我们也看到有很多新人加入软件开发领域。付出如此大的学习代价,获得这么一点点好处,个人觉得并不值得。
楼主明显没有深入研究spring security就发表这么多严重错误的言论。。。。。。 第一条缺点: 你这个所谓的角色被“编码”到配置文件和源文件,是因为你使用了spring自带的RoleVoter,AuthenticatedVoter和DefaultFilterInvocationDefinitionSource造成的,你为了图方便而直接使用了这3个现成的类,反过来说spring不能怎么怎么样,岂不是可笑? 你自己直接实现FilterInvocationDefinitionSource接口和AccessDecisionVoter接口,不就可以不用编码到配置或源文件里了吗? 你自己的实现,完全可以动态从用户管理系统中获取所有的GrantedAuthority,根本不需要intercept-url 配置. 而且,就算你想使用intercept-url配置,那spring还留了一个Mapper接口,可以让你把自己管理的角色或者用户组映射到你在XML中配置的角色上. 还有你所谓的"角色大多需要等到系统上线后,才能确定",这个你不觉得是因为你在需求分析之间没有做好"涉众分析"造成的么?一个良好的软件过程,在需求分析之前就应该有了完整的涉众模型,有哪些用户群清清楚楚.
第二条缺点:我没去研究过,不清楚.
第三条缺点:Spring在acegi时代就提供了细粒度的解决方法,只不过无法结合数据库里的权限信息进行自动判断,毕竟没有这么智能.但是基于角色或者用户组的数据级过滤完全OK.大数据量下我就曾用过,过滤数据的开销是有一些,但绝对没你说的那么夸张,甚至不可用.
第四条缺点:维护用户、角色、权限之间的关系,你不觉得这个应该是用户管理系统的任务么?你不能要求一个认证授权框架来提供这么多应用级别的功能吧.何况spring对各种常用的用户管理系统都提供了良好的接口和默认实现.
第五条缺点: 最新2.0.4版本的配置文件相对acegi已经少了很多了,如果是普通的需求,学习成本还是可以接受的,如果你要完全个性化定义,无论你使不使用spring,成本都很高.而且,在软件设计中,这部分实现的设计工作也不会落到开发工程师头上,由架构组进行设计,到了开发人员手上已经是详细的类图和时序图了,还有什么难度?一个团队里,不是所有人都需要去学这个的.大部分人往往只要会用tag和SecurityContextHolder.getContext().getAuthentication()就OK了.
|
|
返回顶楼 | |
发表时间:2009-04-13
最后修改:2009-04-13
TO: downpour
Metadmin Access Manager没有像Spring Security那样提供配置文件方式,或者@annotation,这种非常柔和的侵入方式。Metadmin采用API侵入模式,在需要调用权限的地方调用一下Metadmin API。(Metadmin在决策权限方面,也提供了类似Spring Security那样配置侵入模式。但我们还是建议开发者使用API侵入,或者将Metadmin服务封装为系统的Proxy、AOP 的Bean等。 ) API格式: // 查询权限:获取当前用户能够查询的员工数据 Collection employees=WebMetadminService.query( req, Constants.SELECT_EMPLOYEE_PVLG_ID ); // 决策权限:判断当前用户能否删除该员工 if( WebMetadminService.permit( req, Constants.DELETE_EMPLOYEE_PVLG_ID, employee ) ) { // 进行权限判断,如果有权限,执行dao删除方法 dao.deleteEmployee( id ); } else { // 如果没有权限,可以跳转到提示页面。 // 拒绝理由,已经保存在request对象里面里面,attribute的名字是"denyReason"的。 } 细粒度的权限逻辑、RBAC角色、权限、用户之间关系,都可以通过Metadmin界面来设置。RBAC的数据,也可以直接写到数据库表里面,由Metadmin读取。 细粒度的权限逻辑,Metadmin采取策略授权模式,将各种权限需求转化为策略。由Metadmin策略引擎解析。将各种权限需求转化为策略,可以在Metadmin提供的设计器完成设计。 Metadmin可以保护:url,数据等资源,间接的保护方法资源。 |
|
返回顶楼 | |
发表时间:2009-04-13
TO: downpour
(补充一下) 系统需要权限判断地方,都需要在Metadmin Access Manager定义为一个权限。比如删除员工、查询员工,删除员工链接是否显示,机构下拉框显示内容等,都被定义为一个权限。 按照权限返回内容,可以将权限分为2大类:1,查询权限,返回数据集合;2,决策权限,返回true/false,以及拒绝理由。 |
|
返回顶楼 | |
发表时间:2009-04-13
guoxu1231 写道 我个人认为Spring Security存在以下几个硬伤:
1. 角色被“编码”到配置文件和源文件,这样最终用户就不能创建角色了。但最终用户期望自己来控制角色。因为在项目实施过程中,客户可能并不能确定有哪些角色,以及角色怎么分配给系统用户。角色大多需要等到系统上线后,才能确定。这些编码有: a) url的权限控制,<intercept-url pattern="/**" access="ROLE_USER" />; b) java方法的权限控制,@Secured("IS_AUTHENTICATED_ANONYMOUSLY"); c) java方法的权限控制,<protect method="set*" access="ROLE_ADMIN" />; 从Acegi时代就支持了, 主要是重新实现下FilterInvocationDefinitionSource这个类. 参考SpringSide http://www.springside.org.cn/docs/reference/Acegi4.htm 2. RBCA这种被广泛运用的模型,没有在Spring Security体现出来; Spring Security支持RBCA, Spring Security sample里是users和authorities两层权限控制, 再加一层role或二层没什么本质区别. 以前做过一个系统权限控制比较麻烦,分了user,role,permission,resource四层. 3. Spring Security没有提供好的细粒度(数据级)权限方案,提供的缺省实现维护工作量大,在大数据量情况下,几乎不可用; 数据级权限控制,觉得LZ提的可能是ACL(Access Control Lists) Based Security. ACL和RBAC这两种安全控制模型差异很大,这个貌似Spring Security不支持的吧? 有了解的童鞋可以跟贴解释下 http://alt.pluralsight.com/wiki/default.aspx/Keith.GuideBook/WhatIsACLBasedSecurity.html 以前用过acegisecurity,也说说我的感受吧。 第一个:无论acegisecurity, 还是spring security,DEMO确实是配置于XML文件中,但是我们可以自己扩展,将这些信息存储到数据库中,url, method, acl都留有接口,供我们扩展。。。 第二个:大型系统中尚未用到过。 第三个:acl是和业务逻辑关联得比较紧密,既然和业务逻辑相关,那么我认为其中很大一部分逻辑是可能通过SQL来处理的,这样不紧降低了开发难度,而且即使以后有变动,修改的也少。 以上仅仅是个人的一些见解。 |
|
返回顶楼 | |
发表时间:2009-04-13
llade 写道 [quote="daquan198163可以的,SS的标签库就是做这个的。
但我觉得它自带的标签库有问题:<security:authorize ifAllGranted="ROLE_admin">xx</security:authorize> 这样就把角色写死在页面里了,我觉得更好的做法是 <security:authorize ifAllGranted="/xx.do">xx</security:authorize>,即声明这个被保护的页面元素对应了哪个资源,至于这个资源需要哪个角色标签库程序是很容易获得的,进而计算是否有权查看。 问题是ROLE就很多了。有些ROLE不能预设,比如,突然来了个 “南京纪检组”,必须动态的加的。 URL,METHOD,ROLE,Resource等等这些,通常情况下是固定的,也就是说:很少会有变动,即使变动,数据量也比较小,可以考虑存储在Cache中,如果有变动的话,重新添加进CACHE或刷新cache即可。 还有secutity标签,本身留有接口,可以自己重新实现. |
|
返回顶楼 | |
发表时间:2009-04-13
justshare 写道 llade 写道 [quote="daquan198163可以的,SS的标签库就是做这个的。
但我觉得它自带的标签库有问题:<security:authorize ifAllGranted="ROLE_admin">xx</security:authorize> 这样就把角色写死在页面里了,我觉得更好的做法是 <security:authorize ifAllGranted="/xx.do">xx</security:authorize>,即声明这个被保护的页面元素对应了哪个资源,至于这个资源需要哪个角色标签库程序是很容易获得的,进而计算是否有权查看。 问题是ROLE就很多了。有些ROLE不能预设,比如,突然来了个 “南京纪检组”,必须动态的加的。 URL,METHOD,ROLE,Resource等等这些,通常情况下是固定的,也就是说:很少会有变动,即使变动,数据量也比较小,可以考虑存储在Cache中,如果有变动的话,重新添加进CACHE或刷新cache即可。 还有secutity标签,本身留有接口,可以自己重新实现. 我说的是xx.do能表示的东西相当有限,并且不那么直观。 问个问题:假如有编辑按钮南京纪检组可见,删除按钮扬州不可见,添加意见按钮江苏可见? 是否ifAllGranted="/xx.do"里面设置?不管ifAllGranted是什么,它总要等于某个东西吧。不可能是ROLE_USER之类的所有用户统称吧。 按我的习惯就会用el表达式:${button_edit}${button_delete}${button_comment}照写,其他权限逻辑放在某个ACL Voter里,而真正个过滤规则写在脚本或者由图形界面管理了,过滤完成之后只要request.setAttribute将按钮代码设进去,不显示的按钮就留空或者占位符,按钮代码也是在某个地方配置。页面上就没有ifAllGranted. |
|
返回顶楼 | |
发表时间:2009-04-13
只讲到了spring security的角色认证这块外
spring security的ACL授权(访问控制列表)这块没涉及 |
|
返回顶楼 | |