论坛首页 Java企业应用论坛

Spring Security优劣之我见

浏览 135484 次
该帖已经被评为良好帖
作者 正文
   发表时间:2009-04-10  
<security:authorize ifAllGranted="ROLE_admin">xx</security:authorize>

这种做法和添加权限码是一样的,我的想法是,因为在分配操作权限的时候,已经分配了一次,在那里可以指定某个操作的权限,维护一个操作的权限树,然后给该角色分配。可以用二进制的与来判断该角色是否具有该权限。但是有一点就是这个树很难包容变化,稍微变化了可能就乱套了。

树的结构:

---公告
      ----新增
      ----修改
      ----删除
---投诉
      ----新增
      ----修改
      ----删除

对于公告权限表达是三位数字 001 表示有删除功能

以上都类似
0 请登录后投票
   发表时间:2009-04-10  
发现了Apache也有一个权限的安全框架,不过还在Incubator中。框架名字叫Ki

一个介绍其的PPT : http://cwiki.apache.org/KI/articles.data/Ki-DevNexus-2009.pdf

MS这个框架也不错。

不知道有没有研究过这个东东啊?
0 请登录后投票
   发表时间: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


你没有明白我的意思。你给我看的,是你做的产品。我并不关心你做了什么产品,我所关心的是我如何将你的产品运用到我自己的项目中去,从而实现数据访问权限的控制。

请解释一下。
1 请登录后投票
   发表时间: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就发表这么多严重错误的言论。。。。。。
就你所说的几个所谓“硬伤”,除了RBCA我不清楚外,其他都是误解。

第一条缺点: 你这个所谓的角色被“编码”到配置文件和源文件,是因为你使用了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了.

 

 

 

3 请登录后投票
   发表时间: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,数据等资源,间接的保护方法资源。
0 请登录后投票
   发表时间:2009-04-13  
TO: downpour
(补充一下)
系统需要权限判断地方,都需要在Metadmin Access Manager定义为一个权限。比如删除员工、查询员工,删除员工链接是否显示,机构下拉框显示内容等,都被定义为一个权限。

按照权限返回内容,可以将权限分为2大类:1,查询权限,返回数据集合;2,决策权限,返回true/false,以及拒绝理由。
0 请登录后投票
   发表时间: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来处理的,这样不紧降低了开发难度,而且即使以后有变动,修改的也少。
以上仅仅是个人的一些见解。
0 请登录后投票
   发表时间: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标签,本身留有接口,可以自己重新实现.
0 请登录后投票
   发表时间: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.

0 请登录后投票
   发表时间:2009-04-13  
只讲到了spring security的角色认证这块外
spring security的ACL授权(访问控制列表)这块没涉及

0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics