`
阅读更多

Spring Security 优劣

 

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

 

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

 

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

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

文章大纲:

Spring Security 如何控制权限

    概要

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

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

Spring Security 如何控制权限

概要

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

 

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

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

比如: 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 EE Filter (非 Spring Filter )机制,将需要权限判断的 url ,“牵引”给 Spring Filter Chain 即可。

 

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

控制内容

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

1.       url

2.       bean method

3.       http session

 

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

 

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

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

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

 

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

 

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

1.       remember me ,记住我;

2.       form-login 登录控制;

3.       多种身份认证功能;

4.       用户密码加密和“ salt ”功能;

5.       http 协议控制;

6.       访问端口控制;

7.       Pre-Invocation & After-Invocation

 

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

 

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

 

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

 

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

 

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

 

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

 

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

细粒度权限控制

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

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

 

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

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

 

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

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

访问用户

被访问数据

授权操作

张三

华北电力客户 1

读取

张三

华北电力客户 2

读取

李四

华南电力客户 1

读取

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

1.       和业务数据绑定死了,业务数据的增 / 删,需要维护该权限表;

2.       在大数据量的情况下,系统效率低下。

 

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

我们理想中的权限管理

客户对权限管理的需求

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

1.       自主灵活地管理角色、角色权限,并将角色赋予系统相关用户;

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

3.       没有功能的按钮、菜单、数据等等,就不要在界面上出现了。

开发中遇到的难点

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

 

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

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

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

我们理想的权限管理

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

1.       能实现角色级权限;能实现数据级权限;

2.       简单、易操作,能够应对各种需求;

3.       应对需求变更能力强;

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

 

Spring Security 的评价

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

 

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

优点

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

1.       提供了一套权限框架,这套框架是可行的;

2.       提供了很多用户身份认证功能,可以节约大量开发工作;

3.       提供了角色判断功能,这点既是优点又是缺点;

4.       提供了 form-login remember me 等控制。

 

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

缺点

我个人认为 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" />

2.       RBCA 这种被广泛运用的模型,没有在 Spring Security 体现出来;

3.       Spring Security 没有提供好的细粒度(数据级)权限方案,提供的缺省实现维护工作量大,在大数据量情况下,几乎不可用;

4.       Spring Security 对于用户、角色、权限之间的关系,没有提供任何一种维护界面。不过从 Spring Security 角度看,确实没有必要有界面。角色创建、角色和权限直接的关系,都被“编码”到配置文件和源文件了;

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

分享到:
评论

相关推荐

    spring.net中文手册在线版

    Spring.NET是一个应用程序框架,其目的是协助开发人员创建企业级的.NET应用程序。它提供了很多方面的功能,比如依赖注入、面向方面编程(AOP)、数据访问抽象及ASP.NET扩展等等。Spring.NET以Java版的Spring框架为...

    spring源码合集spring源码合集

    spring

    spring3.1 官方全部jar包

    spring3.1官方所有的jar包 org.springframework.aop-3.1.RELEASE.jar org.springframework.asm-3.1.RELEASE.jar org.springframework.aspects-3.1.RELEASE.jar org.springframework.beans-3.1.RELEASE.jar org....

    Spring MVC 入门实例

    这篇文章将教你快速地上手使用 Spring 框架. 如果你手上有一本《Spring in Action》, 那么你最好从第三部分"Spring 在 Web 层的应用--建立 Web 层"开始看, 否则那将是一场恶梦! 首先, 我需要在你心里建立起 Spring...

    Getting started with Spring Framework: covers Spring 5(epub)

    Getting started with Spring Framework (4th Edition) is a hands-on guide to begin developing applications using Spring Framework 5. The examples (consisting of 88 sample projects) that accompany this ...

    最新版本的Struts2+Spring4+Hibernate4框架整合

    项目原型:Struts2.3.16 + Spring4.1.1 + Hibernate4.3.6 二、 项目目的: 整合使用最新版本的三大框架(即Struts2、Spring4和Hibernate4),搭建项目架构原型。 项目架构原型:Struts2.3.16 + Spring4.1.1 + ...

    spring源码分析(1-10)

    Spring源代码解析(一):Spring中的事务处理 Spring源代码解析(二):ioc容器在Web容器中的启动 Spring源代码分析(三):Spring JDBC Spring源代码解析(四):Spring MVC Spring源代码解析(五):Spring AOP获取Proxy ...

    spring3.0.0相关jar包

    spring3.0.0相关jar包 org.springframework.aop-3.0.0.RELEASE org.springframework.asm-3.0.0.RELEASE org.springframework.aspects-3.0.0.RELEASE org.springframework.beans-3.0.0.RELEASE org.springframework....

    SpringBoot+SpringCloud面试题.doc

    Spring boot 是 Spring 的一套快速配置脚手架,可以基于spring boot 快速开发单个微服务,Spring Cloud是一个基于Spring Boot实现的云应用开发工具;Spring boot专注于快速、方便集成的单个个体,Spring Cloud是关注...

    spring 3.2.4.RELEASE jar包

    spring 3.2.4 Realease 的所有jar包: spring-context-3.2.4.RELEASE.jar spring-core-3.2.4.RELEASE.jar spring-beans-3.2.4.RELEASE.jar spring-test-3.2.4.RELEASE.jar spring-web-3.2.4.RELEASE.jar spring-aop-...

    spring-mock.jar

    Classes contained in spring-mock.jar: org.springframework.mock.jndi.ExpectedLookupTemplate.class org.springframework.mock.jndi.SimpleNamingContext.class org.springframework.mock.jndi....

    开发工具 spring-aop-4.3.6.RELEASE

    开发工具 spring-aop-4.3.6.RELEASE开发工具 spring-aop-4.3.6.RELEASE开发工具 spring-aop-4.3.6.RELEASE开发工具 spring-aop-4.3.6.RELEASE开发工具 spring-aop-4.3.6.RELEASE开发工具 spring-aop-4.3.6.RELEASE...

    spring4.3.1官方全套jar包下载

    spring4.3.1全套jar下载。 4.3.1/spring-aop-4.3.1.RELEASE.jar 4.3.1/spring-aspects-4.3.1.RELEASE.jar 4.3.1/spring-beans-4.3.1.RELEASE.jar 4.3.1/spring-context-4.3.1.RELEASE.jar 4.3.1/spring-core-4.3.1....

    基于spring cloud 和vue全家桶的开源电商源码

    基于spring cloud 和vue全家桶的开源电商源码基于spring cloud 和vue全家桶的开源电商源码基于spring cloud 和vue全家桶的开源电商源码基于spring cloud 和vue全家桶的开源电商源码基于spring cloud 和vue全家桶的...

    Spring技术内幕:深入解析Spring架构与设计原理(第2部分)

    Spring技术内幕:深入解析Spring架构与设计原理(第2部分) 《Spring技术内幕:深入解析Spring架构与设计原理》是Spring领域的问鼎之作,由业界拥有10余年开发经验的资深Java专家亲自执笔!Java开发者社区和Spring...

    Spring in Action 中文版 第五部分(Spring in Action CN.005)

    Spring in Action CN.001&lt;br&gt;Spring in Action CN.002&lt;br&gt;Spring in Action CN.003&lt;br&gt;Spring in Action CN.004&lt;br&gt;Spring in Action CN.005&lt;br&gt;Spring in Action CN.006&lt;br&gt;Spring in Action CN.007&lt;br&gt;Spring in ...

    org.spring-framework-3.0.4. 所有jar

    org.springframework.aop-3.0.4.RELEASE.jar org.springframework.asm-3.0.4.RELEASE.jar org.springframework.aspects-3.0.4.RELEASE.jar org.springframework.beans-3.0.4.RELEASE.jar org.springframework....

    尚硅谷SpringCloud第2季2020版.mmap

    一篇很好的springCloud学习的思维导读,详细的介绍了,springCloud的搭建步骤以及各组件的说明讲解 涵盖 Eureka服务注册与发现 Zookeeper服务注册与发现 Consul服务注册与发现 Ribbon负载均衡服务调用 OpenFeign...

    spring cloud 体系版本选型,涉及spring cloud alibaba spring boot spring cloud

    spring boot , spring cloud alibaba, spring cloub 版本选型

    Spring从入门到精通 源码

    本书由浅入深,循序渐进地介绍了Spring的体系结构和相关知识点,目的是帮助初学者快速掌握Spring,并能使用Spring进行应用程序的开发。本书最大的特色在于每章都是由浅入深,从一个简单的示例入手,让读者快速了解本...

Global site tag (gtag.js) - Google Analytics