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、SpringMVC和Mybatis是Java开发中最常用的三大开源框架,它们的整合使用,通常被称为SSM框架。这个框架组合提供了完整的后端服务解决方案,包括依赖注入(DI)、面向切面编程(AOP)、模型-视图-控制器(MVC...
弃用了struts,用spring mvc框架做了几个项目,感觉都不错,而且使用了注解方式,可以省掉一大堆配置文件。本文主要介绍使用注解方式配置的spring mvc,之前写的spring3.0 mvc和rest小例子没有介绍到数据层的内容,...
java *spring工具类 方便在非spring管理环境中获取beanjava *spring工具类 方便在非spring管理环境中获取beanjava *spring工具类 方便在非spring管理环境中获取beanjava *spring工具类 方便在非spring管理环境中获取...
Spring Integration + Spring WS 整合 在 Java 领域中,Spring Integration 和 Spring WS 是两个常用的框架,它们分别负责集成系统和 Web 服务。今天,我们将探讨如何将这两个框架整合在一起,实现一个完整的 Web ...
包含spring 3.0.5的所有jar文件: org.springframework.aop-3.0.5.RELEASE.jar org.springframework.asm-3.0.5.RELEASE.jar org.springframework.aspects-3.0.5.RELEASE.jar org.springframework.beans-3.0.5.RELEASE...
Spring Batch是一个轻量级的,完全面向Spring的批处理框架,可以应用于企业级大量的数据处理系统。Spring Batch以POJO和大家熟知的Spring框架为基础,使开发者更容易的访问和利用企业级服务。Spring Batch可以提供...
Spring框架是Java应用程序开发中的一个核心组件,它提供了一个丰富的IOC(Inversion of Control,控制反转)和AOP(Aspect-Oriented Programming,面向切面编程)功能,使得开发者能够更方便地管理对象和实现模块化...
在Java开发领域,Spring Boot和Spring Batch的整合是构建高效批处理系统的一种常见方式。Spring Boot以其简洁的配置和快速的启动能力深受开发者喜爱,而Spring Batch作为Spring框架的一部分,专注于批量处理任务,...
在构建分布式系统时,Spring Cloud Gateway 作为微服务架构中的边缘服务或 API 网关,扮演着至关重要的角色。它负责路由请求到相应的微服务,并可以提供过滤器功能,如限流、熔断等。而Spring Security 则是 Java ...
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 框架. 如果你手上有一本《Spring in Action》, 那么你最好从第三部分"Spring 在 Web 层的应用--建立 Web 层"开始看, 否则那将是一场恶梦! 首先, 我需要在你心里建立起 Spring...
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 ...
介绍一个基于Spring Boot 3.0、Spring Cloud 2022 & Alibaba的微服务RBAC权限管理系统。该系统可以实现微服务RBAC权限管理,通过RBAC权限管理机制对用户访问系统的权限进行限制,从而提高系统的安全性和可用性。同时...
项目原型:Struts2.3.16 + Spring4.1.1 + Hibernate4.3.6 二、 项目目的: 整合使用最新版本的三大框架(即Struts2、Spring4和Hibernate4),搭建项目架构原型。 项目架构原型:Struts2.3.16 + Spring4.1.1 + ...
Spring Cloud和Spring Boot是两个非常重要的Java开发框架,它们在微服务架构中扮演着核心角色。Spring Boot简化了创建独立的、生产级别的基于Spring的应用程序的过程,而Spring Cloud则为开发者提供了快速构建分布式...
《Spring AI Core 0.8.1:开启人工智能之旅》 在现代软件开发领域,Spring框架以其强大的功能和灵活性,已经成为Java开发中的首选框架之一。而Spring AI Core则是Spring生态系统中专门为人工智能(AI)和机器学习...
《Spring技术内幕:深入解析Spring架构与设计原理(第2版)》从源代码的角度对Spring的内核和各个主要功能模块的架构、设计和实现原理进行了深入剖析。你不仅能从本书中参透Spring框架的出色架构和设计思想,还能从...
Spring 框架是 Java 开发中的一个核心组件,它为构建企业级应用程序提供了全面的编程和配置模型。Spring 4.3.14 是该框架的最后一个4.x系列正式版,发布于2018年2月24日。这个版本在Spring 5.0发布之前提供了一个...
在IT行业中,Spring框架是Java应用开发中的一个关键组件,它提供了一整套服务来简化企业级应用的构建。RabbitMQ则是一个流行的开源消息队列系统,它基于AMQP(Advanced Message Queuing Protocol)协议,用于高效地...
Spring Cloud系列教程 Spring Boot Spring Cloud Stream 和 Kafka案例教程 springcloud生产者与消费者项目实战案例 Spring Cloud 中断路器 Circuit Breaker的应用 配置 Spring Cloud Config Server Spring Cloud ...