`
metadmin
  • 浏览: 168405 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

Spring Security优劣之我见

阅读更多

<!--[if !mso]> <style> v\:* {behavior:url(#default#VML);} o\:* {behavior:url(#default#VML);} w\:* {behavior:url(#default#VML);} .shape {behavior:url(#default#VML);} </style> <![endif]--><!--[if gte mso 9]><xml> <w:WordDocument> <w:View>Normal</w:View> <w:Zoom>0</w:Zoom> <w:PunctuationKerning /> <w:DrawingGridVerticalSpacing>7.8 磅</w:DrawingGridVerticalSpacing> <w:DisplayHorizontalDrawingGridEvery>0</w:DisplayHorizontalDrawingGridEvery> <w:DisplayVerticalDrawingGridEvery>2</w:DisplayVerticalDrawingGridEvery> <w:Compatibility> <w:SpaceForUL /> <w:BalanceSingleByteDoubleByteWidth /> <w:DoNotLeaveBackslashAlone /> <w:ULTrailSpace /> <w:DoNotExpandShiftReturn /> <w:AdjustLineHeightInTable /> <w:BreakWrappedTables /> <w:SnapToGridInCell /> <w:WrapTextWithPunct /> <w:UseAsianBreakRules /> <w:UseFELayout /> </w:Compatibility> <w:BrowserLevel>MicrosoftInternetExplorer4</w:BrowserLevel> </w:WordDocument> </xml><![endif]--> <!--[if gte mso 10]> <style> /* Style Definitions */ table.MsoNormalTable {mso-style-name:普通表格; mso-tstyle-rowband-size:0; mso-tstyle-colband-size:0; mso-style-noshow:yes; mso-style-parent:""; mso-padding-alt:0cm 5.4pt 0cm 5.4pt; mso-para-margin:0cm; mso-para-margin-bottom:.0001pt; mso-pagination:widow-orphan; font-size:10.0pt; font-family:宋体; mso-ascii-font-family:"Times New Roman"; mso-hansi-font-family:"Times New Roman";} table.MsoTableGrid {mso-style-name:网格型; mso-tstyle-rowband-size:0; mso-tstyle-colband-size:0; border:solid windowtext 1.0pt; mso-border-alt:solid windowtext .5pt; mso-padding-alt:0cm 5.4pt 0cm 5.4pt; mso-border-insideh:.5pt solid windowtext; mso-border-insidev:.5pt solid windowtext; mso-para-margin:0cm; mso-para-margin-bottom:.0001pt; text-align:justify; text-justify:inter-ideograph; mso-pagination:none; font-size:10.0pt; font-family:宋体; mso-ascii-font-family:"Times New Roman"; mso-hansi-font-family:"Times New Roman";} </style> <![endif]-->

Spring Security优劣之我见

 

拜读了Spring Security相关帖子和Spring Security参考文档。现将我理解的Spring Security写下来和大家共享。

 

本文目的是从Spring Security能够提供的功能、以及基本原理角度分析,并不深入到如何编码。然后反过来,审查我们的软件系统需要哪些权限控制。进而评审Spring Security的适用性。

 

本文力求文字简单,概念也简单。

--------------------------------------------------------------

文章大纲:

Spring Security 如何控制权限

    概要

    与WEB系统的集成
    控制内容
    细粒度权限控制
我们理想中的权限管理
    客户对权限管理的需求
    开发中遇到的难点
    我们理想的权限管理
Spring Security的评价
    优点
    缺点

--------------------------------------------------------------

Spring Security如何控制权限

概要

Spring使用由Filter组成的Chain,来判断权限。如下图所示:

<!--[if gte vml 1]><v:shapetype id="_x0000_t75" coordsize="21600,21600" o:spt="75" o:preferrelative="t" path="m@4@5l@4@11@9@11@9@5xe" filled="f" stroked="f"> <v:stroke joinstyle="miter" /> <v:formulas> <v:f eqn="if lineDrawn pixelLineWidth 0" /> <v:f eqn="sum @0 1 0" /> <v:f eqn="sum 0 0 @1" /> <v:f eqn="prod @2 1 2" /> <v:f eqn="prod @3 21600 pixelWidth" /> <v:f eqn="prod @3 21600 pixelHeight" /> <v:f eqn="sum @0 0 1" /> <v:f eqn="prod @6 1 2" /> <v:f eqn="prod @7 21600 pixelWidth" /> <v:f eqn="sum @8 21600 0" /> <v:f eqn="prod @7 21600 pixelHeight" /> <v:f eqn="sum @10 21600 0" /> </v:formulas> <v:path o:extrusionok="f" gradientshapeok="t" o:connecttype="rect" /> <o:lock v:ext="edit" aspectratio="t" /> </v:shapetype><v:shape id="_x0000_i1025" type="#_x0000_t75" style="width:414.75pt; height:174pt" mce_style="width:414.75pt; height:174pt"> <v:imagedata src="file:///C:\DOCUME~1\back\LOCALS~1\Temp\msohtml1\01\clip_image001.png" mce_src="file:///C:\DOCUME~1\back\LOCALS~1\Temp\msohtml1\01\clip_image001.png" o:title=""Ĥ" /> </v:shape><![endif]--><!--[if !vml]--><!--[endif]-->

Spring预定义了很多out-of-boxed filter供开发者直接使用。

每个Filter一般情况下(有些Filterabstract的),都和配置文件的一个元素(有的情况下可能是属性)对应。

比如:AUTHENTICATION_PROCESSING_FILTER,对应配置文件里面的:http/form-login元素。

 

如果Spring提供的Filter不能满足系统的权限功能,开发者可以自定义Filter,然后把Filter放在某个Filter Chain的某个位置。可以替换掉原有Filter Chain的某个Filter,也可以放在某个Filter之前或者之后。

 

总之,Spring Security采用Filter Chain模式判断权限,Spring提供了一些Filter,也支持开发者自定义Filter

WEB系统的集成

使用Java EEFilter(非SpringFilter)机制,将需要权限判断的url,“牵引”给SpringFilter Chain即可。

 

一般情况下,将所有的url都引入Filter Chain。当然也可以在web.xml配置需要权限判断的url(配置filter-mapping/url-pattern)。Spring的配置文件也支持过滤掉不需要权限判断的url(配置http/intercept-url元素)。

控制内容

Spring Security提供了如下内容的控制:

<!--[if !supportLists]-->1.       <!--[endif]-->url

<!--[if !supportLists]-->2.       <!--[endif]-->bean method

<!--[if !supportLists]-->3.       <!--[endif]-->http session

 

url:可以分为需要权限判断的url,不需要权限判断的url,登录表单url。通过我对spring相关帖子和参考文档的阅读,需要权限判断的url。仅限于做角色判断,就是说判断当前用户是否具有指定的角色。

 

bean methodSpring支持对Service layer method做权限判断。通过我对spring相关帖子和参考文档的阅读,也仅限于做角色判断。配置方式有2种:

<!--[if !supportLists]-->1.       <!--[endif]-->写在Java源代码里面,如:@Secured("ROLE_TELLER")(该方法只有具有TELLER角色的用户能够访问,否则抛出异常);

<!--[if !supportLists]-->2.       <!--[endif]-->写在配置文件里面,如:<protect method="set*" access="ROLE_ADMIN" />(该bean的所有set方法,只有具有ADMIN角色的用户能够访问,否则抛出异常)。

 

http session:控制一个用户名是否能重复登录,以及重复登录次数,并非重试密码次数。

 

另外,Spring Security还提供了如下一些功能:

<!--[if !supportLists]-->1.       <!--[endif]-->remember me,记住我;

<!--[if !supportLists]-->2.       <!--[endif]-->form-login登录控制;

<!--[if !supportLists]-->3.       <!--[endif]-->多种身份认证功能;

<!--[if !supportLists]-->4.       <!--[endif]-->用户密码加密和“salt”功能;

<!--[if !supportLists]-->5.       <!--[endif]-->http协议控制;

<!--[if !supportLists]-->6.       <!--[endif]-->访问端口控制;

<!--[if !supportLists]-->7.       <!--[endif]-->Pre-Invocation & After-Invocation

 

remember me,记住我:还记得浏览器采用cookie记住用户名和密码自动登录吗?好像就是这个(不知道我理解错了没有,应该没有。只是我不大敢相信)。使用这个功能,开发者在登录页面,使用spring自定义的标签。

 

form-login登录控制:有些页面不允许匿名访问,那么当匿名访问这些页面的时候,将弹出(或者转到)form-login窗口(或者页面)。这里又牵引出2个问题:1,输入用户名和密码后怎样验证;2,密码是否需要加密,怎么加密。

 

多种身份认证功能:Spring提供了丰富的用户身份认证功能。身份认证是什么意思?比如您告诉我“我是神仙”。那么我会问您“凭什么证明您是神仙”。这就是身份认证。认证手段一般是保存到数据库表的用户名/密码,usb keyldap等。一般情况下,我们都使用用户名/密码的。

 

用户密码加密和“salt”功能:密码采用md5,还是sha加密算法。如果我们对密码加密的时候,不想仅仅对密码加密,还想把用户名和密码放在一起加密做为加密后的密码。那么使用salt吧。salt支持也读取用户的其他属性,不仅是用户名。

 

http协议控制:哪些url,必须采用https访问呢?哪些url必须采用http访问呢?哪些又两者都可以呢?通过这个配置。

 

访问端口控制:类似http协议控制,控制url和访问端口之间的关系。

 

Pre-Invocation & After-Invocation:在方法调用之前做权限判断,还是方法调用之后做权限判断呢?一般情况下是之前调用。也有情况下是之后调用。具体例子可以看官方文档(22.3小节)。

细粒度权限控制

由上面分析,我们看到urlmethod的权限判断,都仅限于用户角色权限判断。事实上Spring使用投票(Voter)机制,来做权限判断。用户角色权限也是一种投票。

投票这个词,听起来不容易懂。举例:董事会开会,各个股东投票以表决决议是否通过。Spring的角色投票器,只会投出一票。我们平时所说的投票至少要2张票吧,一张还叫什么投票。Spring的投票有3种结果:允许、拒绝和弃权。弃权?真的有点晕。呵呵,这种情况下还弃权。

 

那么投票器,如何集成到SpringFilter里面呢?

SpringFilter一般都由一个Manager支撑着。比如accessDecisionManager,可以由RoleVoterBasicAclEntryVoter提供投票。accessDecisionManager根据RoleVoterBasicAclEntryVoter投票结果,做出决策判断。

 

细粒度(数据级)的权限控制,Spring Security提供了一种模型以及相关实现。下面我简要说说这个模型。

举例:张三授权查询华北区域客户资料,李四授权查询华南区域客户资料。那么,首先会对所有客户记录做个标示(相当于取个id),然后在acl-entry表给张三授权华北所有客户访问权限;给李四华南区域所有客户权限。表记录大致是这样的:

访问用户

被访问数据

授权操作

张三

华北电力客户1

读取

张三

华北电力客户2

读取

李四

华南电力客户1

读取

这个模型的缺点是非常明显的:

<!--[if !supportLists]-->1.       <!--[endif]-->和业务数据绑定死了,业务数据的增/删,需要维护该权限表;

<!--[if !supportLists]-->2.       <!--[endif]-->在大数据量的情况下,系统效率低下。

 

因此,开发者需要自己书写投票器了。

我们理想中的权限管理

客户对权限管理的需求

这里是指我们服务的最终用户,而不是软件开发者。客户对权限管理的需求,大体可以概括如下:

<!--[if !supportLists]-->1.       <!--[endif]-->自主灵活地管理角色、角色权限,并将角色赋予系统相关用户;

<!--[if !supportLists]-->2.       <!--[endif]-->数据安全。系统展现数据是满足权限的,在系统内部搜索数据也必须在相应权限访问内,对系统数据进行增加、修改、删除必须是满足权限的;

<!--[if !supportLists]-->3.       <!--[endif]-->没有功能的按钮、菜单、数据等等,就不要在界面上出现了。

开发中遇到的难点

管理用户、角色、权限,以及三者之间的关系,这种典型的RBAC模型,非常容易,没有任何困难。

 

困难的是,数据级权限控制。这是和业务直接挂钩的,最复杂,而且会经常因为客户需求表达不到位、开发人员需求理解不到位、系统框架库表结构发生变化,而不断变化的。

这种变化,不仅需要编码,而且还需要重新测试。甚至这种变化会波及到其他模块,甚至整个系统。

系统开发经历几次变化下来,代码里面散布着if/else,散布着sql语句。导致bad smell

我们理想的权限管理

我们期望的权限管理,应该具有这么几个特性:

<!--[if !supportLists]-->1.       <!--[endif]-->能实现角色级权限;能实现数据级权限;

<!--[if !supportLists]-->2.       <!--[endif]-->简单、易操作,能够应对各种需求;

<!--[if !supportLists]-->3.       <!--[endif]-->应对需求变更能力强;

<!--[if !supportLists]-->4.       <!--[endif]-->最好有相关界面,比如权限管理界面、角色管理界面,角色和权限关系维护界面,用户和角色关系维护界面。如果没有界面,也是可以接受的。毕竟这些页面需要最终用户来使用,不同用户对系统的界面要求不同。因此我们并不期望统一的管理界面。

 

Spring Security的评价

Spring Security世界里,可以区分出哪些资源可以匿名访问,哪些需要角色权限,又是哪个页面提供登录功能;怎样进行用户身份认证,用户的密码如何加密。哪些资源必须使用https协议,资源和访问端口有怎样的对应关系。

 

下面就优点和缺点对Spring Security进行点评。

优点

总体说来Spring Security具有以下几个优点:

<!--[if !supportLists]-->1.       <!--[endif]-->提供了一套权限框架,这套框架是可行的;

<!--[if !supportLists]-->2.       <!--[endif]-->提供了很多用户身份认证功能,可以节约大量开发工作;

<!--[if !supportLists]-->3.       <!--[endif]-->提供了角色判断功能,这点既是优点又是缺点;

<!--[if !supportLists]-->4.       <!--[endif]-->提供了form-loginremember me等控制。

 

其中24两点,对于我们中国开发者(我对国外系统不大了解),可用性并不大。我们的系统大多采用用户名/密码身份认证模式,大多公司都有可复用代码。form-loginremember me等这些功能,并不是难以开发,而且可用之处也并不多。

缺点

我个人认为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学习难度大,配置文件还是很多。我承认有很多高手,但我们也看到有很多新人加入软件开发领域。付出如此大的学习代价,获得这么一点点好处,个人觉得并不值得。

 

附言:

本人在JavaEye创建“权限管理”圈子快2周了,吸引不少网友进来。我感到很高兴,也很荣幸。由于Spring Security运用范围还是比较广的,所以我打算好好学习一下,把学习经验和大家分享一下。

 

欢迎大家加入“权限管理”圈子讨论,探讨对权限管理的认识、看法、建议等等。

http://accessmanager.group.iteye.com/

 

分享到:
评论
36 楼 justshare 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来处理的,这样不紧降低了开发难度,而且即使以后有变动,修改的也少。
以上仅仅是个人的一些见解。
35 楼 metadmin 2009-04-13  
TO: downpour
(补充一下)
系统需要权限判断地方,都需要在Metadmin Access Manager定义为一个权限。比如删除员工、查询员工,删除员工链接是否显示,机构下拉框显示内容等,都被定义为一个权限。

按照权限返回内容,可以将权限分为2大类:1,查询权限,返回数据集合;2,决策权限,返回true/false,以及拒绝理由。
34 楼 metadmin 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,数据等资源,间接的保护方法资源。
33 楼 wym0291 2009-04-11  
<div class="quote_title">metadmin 写道</div>
<div class="quote_div">
<h2><span style="font-family: 黑体;">缺点</span></h2>
<p class="MsoNormal"><span style="font-family: 宋体;">我个人认为</span><span lang="EN-US">Spring Security</span><span style="font-family: 宋体;">存在以下几个硬伤:</span></p>
<p class="MsoNormal" style="margin-left: 21pt; text-indent: -21pt;">&lt;!--[if !supportLists]--&gt;<span lang="EN-US"><span>1.<span style="font-family: &quot;Times New Roman&quot;; font-size-adjust: none; font-stretch: normal;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span>&lt;!--[endif]--&gt;<span style="font-family: 宋体;">角色被&ldquo;编码&rdquo;到配置文件和源文件,这样最终用户就不能创建角色了。但最终用户期望自己来控制角色。因为在项目实施过程中,客户可能并不能确定有哪些角色,以及角色怎么分配给系统用户。角色大多需要等到系统上线后,才能确定。这些编码有:</span></p>
<p class="MsoNormal" style="margin-left: 42pt; text-indent: -21pt;">&lt;!--[if !supportLists]--&gt;<span lang="EN-US"><span>a)<span style="font-family: &quot;Times New Roman&quot;; font-size-adjust: none; font-stretch: normal;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span>&lt;!--[endif]--&gt;<span lang="EN-US">url</span><span style="font-family: 宋体;">的权限控制,</span><span lang="EN-US">&lt;intercept-url pattern="/**" access="ROLE_USER" /&gt;</span><span style="font-family: 宋体;">;</span></p>
<p class="MsoNormal" style="margin-left: 42pt; text-indent: -21pt;">&lt;!--[if !supportLists]--&gt;<span lang="EN-US"><span>b)<span style="font-family: &quot;Times New Roman&quot;; font-size-adjust: none; font-stretch: normal;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span>&lt;!--[endif]--&gt;<span lang="EN-US">java</span><span style="font-family: 宋体;">方法的权限控制,</span><span lang="EN-US">@Secured("IS_AUTHENTICATED_ANONYMOUSLY")</span><span style="font-family: 宋体;">;</span></p>
<p class="MsoNormal" style="margin-left: 42pt; text-indent: -21pt;">&lt;!--[if !supportLists]--&gt;<span lang="EN-US"><span>c)<span style="font-family: &quot;Times New Roman&quot;; font-size-adjust: none; font-stretch: normal;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span>&lt;!--[endif]--&gt;<span lang="EN-US">java</span><span style="font-family: 宋体;">方法的权限控制,</span><span lang="EN-US">&lt;protect method="set*" access="ROLE_ADMIN" /&gt;</span><span style="font-family: 宋体;">;</span></p>
<p class="MsoNormal" style="margin-left: 21pt; text-indent: -21pt;">&lt;!--[if !supportLists]--&gt;<span lang="EN-US"><span>2.<span style="font-family: &quot;Times New Roman&quot;; font-size-adjust: none; font-stretch: normal;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span>&lt;!--[endif]--&gt;<span lang="EN-US">RBCA</span><span style="font-family: 宋体;">这种被广泛运用的模型,没有在</span><span lang="EN-US">Spring Security</span><span style="font-family: 宋体;">体现出来;</span></p>
<p class="MsoNormal" style="margin-left: 21pt; text-indent: -21pt;">&lt;!--[if !supportLists]--&gt;<span lang="EN-US"><span>3.<span style="font-family: &quot;Times New Roman&quot;; font-size-adjust: none; font-stretch: normal;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span>&lt;!--[endif]--&gt;<span lang="EN-US">Spring Security</span><span style="font-family: 宋体;">没有提供好的细粒度(数据级)权限方案,提供的缺省实现维护工作量大,在大数据量情况下,几乎不可用;</span></p>
<p class="MsoNormal" style="margin-left: 21pt; text-indent: -21pt;">&lt;!--[if !supportLists]--&gt;<span lang="EN-US"><span>4.<span style="font-family: &quot;Times New Roman&quot;; font-size-adjust: none; font-stretch: normal;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span>&lt;!--[endif]--&gt;<span lang="EN-US">Spring Security</span><span style="font-family: 宋体;">对于用户、角色、权限之间的关系,没有提供任何一种维护界面。不过从</span><span lang="EN-US">Spring Security</span><span style="font-family: 宋体;">角度看,确实没有必要有界面。角色创建、角色和权限直接的关系,都被&ldquo;编码&rdquo;到配置文件和源文件了;</span></p>
<p class="MsoNormal" style="margin-left: 21pt; text-indent: -21pt;">&lt;!--[if !supportLists]--&gt;<span lang="EN-US"><span>5.<span style="font-family: &quot;Times New Roman&quot;; font-size-adjust: none; font-stretch: normal;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span>&lt;!--[endif]--&gt;<span lang="EN-US">Spring Security</span><span style="font-family: 宋体;">学习难度大,配置文件还是很多。我承认有很多高手,但我们也看到有很多新人加入软件开发领域。付出如此大的学习代价,获得这么一点点好处,个人觉得并不值得。</span></p>
<p class="MsoNormal"><span lang="EN-US">&nbsp;</span>&nbsp;</p>
</div>
<p>&nbsp;</p>
<p><img src="/images/smiles/icon_sad.gif" alt="" />&nbsp;楼主明显没有深入研究spring security就发表这么多严重错误的言论。。。。。。<br />就你所说的几个所谓&ldquo;硬伤&rdquo;,除了RBCA我不清楚外,其他都是误解。</p>
<p><span style="color: #ff0000;">第一条缺点: 你这个所谓的角色被&ldquo;编码&rdquo;到配置文件和源文件</span>,是因为你使用了spring自带的RoleVoter,AuthenticatedVoter和DefaultFilterInvocationDefinitionSource造成的,你为了图方便而直接使用了这3个现成的类,反过来说spring不能怎么怎么样,岂不是可笑?</p>
<p>你自己直接实现FilterInvocationDefinitionSource接口和AccessDecisionVoter接口,不就可以不用编码到配置或源文件里了吗?</p>
<p>你自己的实现,完全可以动态从用户管理系统中获取所有的GrantedAuthority,根本不需要intercept-url 配置. 而且,就算你想使用intercept-url配置,那spring还留了一个Mapper接口,可以让你把自己管理的角色或者用户组映射到你在XML中配置的角色上.</p>
<p>还有你所谓的"角色大多需要等到系统上线后,才能确定",这个你不觉得是因为你在需求分析之间没有做好"涉众分析"造成的么?一个良好的软件过程,在需求分析之前就应该有了完整的涉众模型,有哪些用户群清清楚楚.</p>
<p>&nbsp;</p>
<p><span style="color: #ff0000;">第二条缺点:我没去研究过,不清楚.</span></p>
<p>&nbsp;</p>
<p><span style="color: #ff0000;">第三条缺点:</span><span style="color: #000000;">Spring在acegi时代就提供了细粒度的解决方法,只不过无法结合数据库里的权限信息进行自动判断,毕竟没有这么智能.但是基于角色或者用户组的数据级过滤完全OK.大数据量下我就曾用过,过滤数据的开销是有一些,但绝对没你说的那么夸张,甚至不可用.</span></p>
<p>&nbsp;</p>
<p><span style="color: #ff0000;">第四条缺点</span>:维护用户、角色、权限之间的关系,你不觉得这个应该是用户管理系统的任务么?你不能要求一个认证授权框架来提供这么多应用级别的功能吧.何况spring对各种常用的用户管理系统都提供了良好的接口和默认实现.</p>
<p>&nbsp;</p>
<p><span style="color: #ff0000;">第五条缺点: </span><span style="color: #000000;">最新2.0.4版本的配置文件相对acegi已经少了很多了,如果是普通的需求,学习成本还是可以接受的,如果你要完全个性化定义,无论你使不使用spring,成本都很高.而且,在软件设计中,这部分实现的设计工作也不会落到开发工程师头上,由架构组进行设计,到了开发人员手上已经是详细的类图和时序图了,还有什么难度?一个团队里,不是所有人都需要去学这个的.大部分人往往只要会用tag和SecurityContextHolder.getContext().getAuthentication()就OK了.</span></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
32 楼 downpour 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


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

请解释一下。
31 楼 jansel 2009-04-10  
发现了Apache也有一个权限的安全框架,不过还在Incubator中。框架名字叫Ki

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

MS这个框架也不错。

不知道有没有研究过这个东东啊?
30 楼 jansel 2009-04-10  
<security:authorize ifAllGranted="ROLE_admin">xx</security:authorize>

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

树的结构:

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

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

以上都类似
29 楼 llade 2009-04-10  
daquan198163 写道
可以的,SS的标签库就是做这个的。
但我觉得它自带的标签库有问题:<security:authorize ifAllGranted="ROLE_admin">xx</security:authorize>
这样就把角色写死在页面里了,我觉得更好的做法是
<security:authorize ifAllGranted="/xx.do">xx</security:authorize>,即声明这个被保护的页面元素对应了哪个资源,至于这个资源需要哪个角色标签库程序是很容易获得的,进而计算是否有权查看。

问题是ROLE就很多了。有些ROLE不能预设,比如,突然来了个 “南京纪检组”,必须动态的加的。
所以我说应该改成<security:authorize ifAllGranted="/xx.do">xx</security:authorize>这样的方式啊,
资源是很少变的。


/xx.do需要定义xx.do 会很多这样的东西。有时候有些比较变态的要求,某份资料只能几个部门可见,其他平级部门不可见。所以,页面只能保留增加,删除,编辑,保存等基础按钮,而另外的操作需要放在页面流去做,满足某个权限才进入特定的页面流。这样,基础按钮就容易被管理工具管理起来了。

可能我说得不够清楚:
<security:authorize ifAllGranted="ROLE_GROUP_123,ROLE_PERSON_456">xx</security:authorize>

如果PERSON ID是456的人离职了,或者GROUP ID是123的部门撤并了。用到的地方都要改,改起来工作量很可观。

定义为xx.do,就要在某个需要管理这些类别的地方需要定义xx.do后面代表了什么,比如南京,南通,扬州等,yy.do表示江苏、浙江等。或者你可以加后缀.xx_city.do,yy_province.do,但如过要表示南京纪检组呢?xx.do会很长,这是用字符串表示的缺陷,既要管理键"xx.do"还要管理后面的值“某人,某部门”,放在关键字里面会满屏的,不借助工具是很难达到合理管理。这些要看公司的技术积累了。
28 楼 daquan198163 2009-04-10  
llade 写道
[quote="daquan198163可以的,SS的标签库就是做这个的。
但我觉得它自带的标签库有问题:<security:authorize ifAllGranted="ROLE_admin">xx</security:authorize>
这样就把角色写死在页面里了,我觉得更好的做法是
<security:authorize ifAllGranted="/xx.do">xx</security:authorize>,即声明这个被保护的页面元素对应了哪个资源,至于这个资源需要哪个角色标签库程序是很容易获得的,进而计算是否有权查看。

问题是ROLE就很多了。有些ROLE不能预设,比如,突然来了个 “南京纪检组”,必须动态的加的。

所以我说应该改成<security:authorize ifAllGranted="/xx.do">xx</security:authorize>这样的方式啊,
资源是很少变的。
27 楼 llade 2009-04-10  
[quote="daquan198163可以的,SS的标签库就是做这个的。
但我觉得它自带的标签库有问题:<security:authorize ifAllGranted="ROLE_admin">xx</security:authorize>
这样就把角色写死在页面里了,我觉得更好的做法是
<security:authorize ifAllGranted="/xx.do">xx</security:authorize>,即声明这个被保护的页面元素对应了哪个资源,至于这个资源需要哪个角色标签库程序是很容易获得的,进而计算是否有权查看。

问题是ROLE就很多了。有些ROLE不能预设,比如,突然来了个 “南京纪检组”,必须动态的加的。
26 楼 llade 2009-04-10  
jansel 写道
我的场景和LZ的差不多,但是我们一直没有找到解决权限的好办法。

对于数据权限,就是能看到什么看不到什么,这个通常是通过SQL的条件去搞定,但是最后就出现了SQL超长的问题,最后只好在存储过程中搞定了。特殊一点的就是,江苏的能看到南京的,南京的看不到扬州的。这种上下级关系的也要支持

对于操作权限,就是按钮需要不需要显示。这个一般是在按钮上加上权限码,然后检查该用户是否有该权限码。

不知道SS能否搞定这两种权限。


通常的做法是这么个表。

文档  操作人 权限类型 权限
文档1 江苏      群    查看
文档1 南京      群    查看
文档1 扬州      群    查看,编辑
文档1 扬州某人  个人  查看,编辑,删除
文档2 江苏      群    查看
文档2 南京      群    查看
文档2 南京某人  个人  查看,编辑,删除

用数据库做权限存储的,只能通过SQL的条件或存储过程去搞定,因为还有个分页问题,不用数据库内置的能力想不出有什么办法。可能你需要一个缓存。

后一种权限SS没有现成的接口,SS有个问题就是你没有接口询问它你能不能做某个操作,也就是你去操作某个方法,等有没有异常抛出来,捕捉到异常你就没有按某个按钮的权限。这种事情只能按钮带有权限码了,最好这个东西让配置管理工具去做。显示页面的时候,就拿这个人的身份和按钮上的权限比较,得出是否显示。

按钮A 南京某人 个人 可见
按钮B 江苏     群   可见
25 楼 daquan198163 2009-04-10  
jansel 写道
我的场景和LZ的差不多,但是我们一直没有找到解决权限的好办法。
对于数据权限,就是能看到什么看不到什么,这个通常是通过SQL的条件去搞定,但是最后就出现了SQL超长的问题,最后只好在存储过程中搞定了。特殊一点的就是,江苏的能看到南京的,南京的看不到扬州的。这种上下级关系的也要支持

关于细粒度的控制数据权限,我有个想法:比如要求江苏的能看到南京的报表,南京的看不到扬州的报表
那么我可以定义一个资源叫“查看报表”viewReport.do,注册到资源表里,
但这个粒度太大,要么全能看,要么全不能看,
于是我给这个资源增加一个rule属性,里面用来保存权限规则,比如groovy脚本,
里面可以写任意复杂的规则,什么ip范围、时间段、行政级别…… 应该能做的灵活和通用了。

jansel 写道

对于操作权限,就是按钮需要不需要显示。这个一般是在按钮上加上权限码,然后检查该用户是否有该权限码。
不知道SS能否搞定这两种权限。

可以的,SS的标签库就是做这个的。
但我觉得它自带的标签库有问题:<security:authorize ifAllGranted="ROLE_admin">xx</security:authorize>
这样就把角色写死在页面里了,我觉得更好的做法是
<security:authorize ifAllGranted="/xx.do">xx</security:authorize>,即声明这个被保护的页面元素对应了哪个资源,至于这个资源需要哪个角色标签库程序是很容易获得的,进而计算是否有权查看。
24 楼 jansel 2009-04-10  
我的场景和LZ的差不多,但是我们一直没有找到解决权限的好办法。

对于数据权限,就是能看到什么看不到什么,这个通常是通过SQL的条件去搞定,但是最后就出现了SQL超长的问题,最后只好在存储过程中搞定了。特殊一点的就是,江苏的能看到南京的,南京的看不到扬州的。这种上下级关系的也要支持

对于操作权限,就是按钮需要不需要显示。这个一般是在按钮上加上权限码,然后检查该用户是否有该权限码。

不知道SS能否搞定这两种权限。
23 楼 metadmin 2009-04-10  
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
22 楼 metadmin 2009-04-10  
qsrock 写道
看了半天,虽然知道lz在说什么,但是没什么学习资料,学起来不容易啊!

本文的用意是帮助开发者,尤其是初学者,对Spring Secuirty有个大致了解。这样再看其他帖子或者教程的时候,会轻松很多,加快入门速度。

同时,我也站在项目管理的角度,审查Spring Security是否合适在项目里面运用,付出的代价如何,得到多大回报。

21 楼 metadmin 2009-04-10  
看了daquan198163,downpour,guoxu1231关于角色控制的说明,SS也是支持RBAC的。
那在这样的项目里面:客户需要自己创建角色,而且角色将要赋予什么权限在系统上线的时候确定、而且需要修改的话。 建议采用  重新实现下FilterInvocationDefinitionSource这个类。
20 楼 cwx714 2009-04-10  
Spring Security是不容易上手,但再找不到其他比它更好点的权限解决方案了。
19 楼 qsrock 2009-04-10  
看了半天,虽然知道lz在说什么,但是没什么学习资料,学起来不容易啊!
18 楼 downpour 2009-04-10  
metadmin 写道
我博客里面有演示:
http://metadmin.iteye.com/blog/359533


我简单看了一下,你的数据权限那块,我没有能够看到相应的代码,和step by step的操作,我想知道如何应用到具体的项目中去。
17 楼 dada 2009-04-09  
-_-很好奇 Spring Security的ACL真的有人用在大数据量的企业应用当中吗?
一直感觉那只是一个玩具,思想上来看没啥问题,但是牵涉到具体的应用当中根本玩不转。

相关推荐

    springboot常见经典面试题.docx

    - **Spring Boot 如何进行安全控制,如使用 Spring Security?** - **Spring Boot 如何实现微服务间的通信,如使用 Spring Cloud?** 这些都是 Spring Boot 面试中可能会问到的问题,了解并掌握这些知识点将有助于...

    Struct2和springMVC比较共2页.pdf.zi

    3. **集成能力**:Spring MVC作为Spring框架的一部分,可以无缝集成Spring的其他模块,如Spring Data、Spring Security等,这对于大型企业级应用来说是一个显著优势。Struct2虽然也能与其他框架集成,但可能需要更多...

    自己画的以及收集汇总的各大常用流行框架的重要图(原理图、流程图、说明图、架构图...等)

    主要包含以下框架:docker、dubbo、elasticsearch、fastDFS、Git、hashMap、jvm、MongoDB、mybatis、nio、rabbitMQ、Redis、rocketMQ、socket编程、spring、springboot、springcloud、springsecurity、多线程、异常...

    springboot+vue营商环境行动计划管理系统设计与开发-f9uxi java毕业设计源码含数据库

    3. 安全性:利用Spring Security等安全框架,系统可以实现用户认证和授权,保护数据安全。 4. 移动友好:Vue.js的响应式设计,使得系统在不同设备上都能良好运行,满足移动办公需求。 总结,"springboot+vue营商...

    JSP基于SSM民宿预订管理系统可升级SpringBoot源码案例设计.zip

    总结,这个案例提供了一个从传统SSM框架向SpringBoot过渡的实例,帮助开发者理解两种框架的不同特性和优劣,以及如何进行系统升级。在实际开发中,根据项目需求选择合适的框架,结合最佳实践,能有效提升开发效率和...

    基于springBoot课程评价系统源码.zip

    5. **用户认证与授权**: 使用Spring Security或JWT进行用户身份验证和权限控制,确保系统安全。 6. **数据库设计**: 可能包括用户表、课程表、评价表等,涉及关系数据库的设计和优化。 7. **前端技术**: 可能使用...

    《Web服务开发学习实录》源代码

    源代码可能提供了对比SOAP和REST的实例,展示它们在复杂性和效率上的差异,以及在特定场景下的优劣选择。 5. 安全性与认证: Web服务的安全性是关键,包括WS-Security、OAuth、JWT等协议可能在源代码中有所体现。...

    xxl-sso.zip

    首先,SpringBoot 2.0是Java开发者的首选框架之一,它简化了传统的Spring应用程序的创建和部署过程,提供了自动配置、内嵌Servlet容器、健康检查和管理端点等功能。在这个项目中,SpringBoot作为基础框架,负责处理...

    基于SpringBoot技术的导师双选系统源码数据库.doc

    - **安全性考虑**:采用Spring Security框架来实现系统的身份认证和授权,保护敏感信息的安全。 #### 六、系统优势 - **高效性**:利用SpringBoot框架快速搭建系统架构,提高开发效率。 - **灵活性**:通过模块化...

    基于Java的KTV点歌系统源码.zip

    - **安全性**:考虑到用户隐私和数据安全,可能应用了HTTPS、JWT令牌或Spring Security等安全措施。 总的来说,这个基于Java的KTV点歌系统源码为学习者提供了深入理解Web开发、Java技术以及娱乐系统设计的实践机会...

    java常用工具类——个人总结

    以下是我个人对Java中常用工具类的总结,主要涉及了加密、文件上传和日期处理等核心领域。 1. **加密工具类**: - `java.security` 包下的 `MessageDigest` 类用于实现消息摘要算法,如MD5和SHA,常用于数据完整性...

    关于blazeDS的例子

    Remoting服务是BlazeDS的核心功能之一,它使得客户端可以直接调用服务器上的Java方法,就像它们是本地函数一样。这大大简化了客户端与服务器之间的通信,并减少了网络延迟。 4. **数据推送(Live Data Services)*...

    web开发原代码

    关系型数据库如MySQL、PostgreSQL和非关系型数据库如MongoDB、Redis各有优劣,开发者需根据项目需求选择合适的数据库。 4. **服务器和部署**:Web应用运行在服务器上,开发者需要了解如何配置和管理服务器,以及...

Global site tag (gtag.js) - Google Analytics