文档章节

实现基于Spring框架应用的权限控制系统(转)

黄正文
 黄正文
发布于 2013/05/09 22:13
字数 2637
阅读 1539
收藏 10

前注:当我摸到了通过filter拦截权限,通过AOP拦截方法,通过权限控制菜单的时候,猛然发现这一切的一切已经是别人已经发明好的轮子。

摘 要 Spring框架是一个优秀的多层 J2EE系统框架,Spring本身没有提供对系统的安全性支持。Acegi是基于Spring IOC 和
AOP机制实现的一个安全框架。本文探讨了Acegi安全框架中各部件之间的交互,并通过扩展Acegi 数据库设计来实现基于Spring框架的应用的安全控制方法。

   关键词 Spring
;Acegi ;认证; 授权

   引言

  近年来,随着Internet技术的迅猛发展,计算机 网络已深入到了人们的工作、学习和日常生活中,于是,怎样构建安全的 Web应用也成为了当前最热门的话题。Spring是一个基于IoC(Inversion of Control)和AOP( ASPect Oriented
Programming)的构架多层J2EE应用系统的框架。Spring框架正在以其优良的特性吸引了越来越多的开发人员的关注,并在大量的系统开发中被使用。然而,现有的Spring框架本身并没有提供对系统安全性的支持,本文通过介绍一种可用于Spring框架中的安全框架Acegi,并对在Spring框架中使用Acegi实现安全用户认证和资源授权控制进行了较深入的研究和扩展,同时给出了可行的 解决方案

   Spring框架和Acegi安全框架介绍

  1、spring
框架

  Spring框架是由Open
Source开发的一个优秀的多层J2EE系统框架,它为企业级应用提供了一个非常轻量级的解决方案,大大地降低了应用开发的难度与复杂度,提高了开发的速度。

  Spring框架的核心是IoC和AOP。IoC是一种 设计模式,即IoC模式。IoC模式进一步降低了类之间的耦合度,并且改变了传统的对象的创建方法,实现了一种配置式的对象管理方式,Spring框架中由IoC容器负责配置性的对象的管理。IoC模式极大的提高了系统开发与维护的灵活性。

  AOP是一种编程模式,它是从系统的横切面关注问题。传统的面向对象编程OOP主要从系统的垂直切面对问题进行关注,对于系统的横切面关注很少,或者说很难关注,这样当考虑到系统的安全性、日志、事务以及其他企业级服务时,OOP就无能为力了,只能在所有相关类中加入类似的系统服务级的代码。AOP为解决系统级服务问题提供了一种很好的方法。AOP将系统服务分解成方面看待,并为类提供一种声明式系统服务方式。 Java类不需要知道日志服务的存在也不需要考虑相关的代码。所以,用AOP编写的应用程序是松耦合的,代码的复用性就提高了。

  2、Acegi
安全框架

  借助于Spring框架,开发者能够快速构建结构良好的WEB应用,但现有的Spring框架本身没有提供安全相关的解决方案。同样来自于Open
Source
社区的Acegi安全框架为实现基于Spring框架的WEB应用的安全控制提供了一个很好的解决方案。Acegi本身就是利用Spring提供的IoC和AOP机制实现的一个安全框架,它将安全性服务作为J2EE平台中的系统级服务,以AOP
Aspect形式发布。所以借助于Acegi安全框架,开发者能够在Spring使能应用中采用声明式方式实现安全控制。

  Acegi安全框架主要由安全管理对象、拦截器以及安全控制管理组件组成。安全管理对象是系统可以进行安全控制的实体,Acegi框架主要支持方法和URL请求两类安全管理对象;拦截器是Acegi中的重要部件,用来实现安全控制请求的拦截,针对不同的安全管理对象的安全控制请求使用不同的拦截器进行拦截;安全控制管理部件是实际实现各种安全控制的组件,对被拦截器拦截的请求进行安全管理与控制,主要组件包括实现用户身份认证的AuthenticationManager、实现用户授权的 AccessDecisionManager
以及实现角色转换的RunAsManager。安全管理对象、拦截器以及安全控制管理组件三者关系如图1所示。

   Acegi安全框架在基于Spring框架的系统中的应用

  1、分析系统安全性需求

  首先,需要明确进行安全控制的对象,可为业务方法和URL资源。

  其次,需要进一步明确,系统身份认证资料和资源授权信息的数据持久化形式。

  2、Acegi安全系统数据库设计

  在Acegi框架中支持多种安全信息的持久化方式,可以在配置文件中配置或存放在关系数据库。由于在实际应用中,需求是经常发生变化的。所以,在配置文件中配置是满足不了实际应用需求的。然而,Acegi本身对权限表的设计非常简单,users表{username,password,enabled}
和authorities表{username,authority},这样简单的设计肯定无法适用复杂的权限需求。为了解决权限管理的复杂性,在这里引入了role(角色)的概念,使得用户和权限分离,一个用户拥有多个角色,一个角色拥有多个相应的权限,这样就更灵活地支持安全策略。

  同时,为了更好地配合Acegi安全框架,还引入resource(资源)的概念,资源可分为URL和FUNCTION(方法)两种,一个权限可以对应多个资源。具体的数据库设计见图2。

实现基于Spring框架应用的权限控制系统
图1
安全管理对象,拦截器和安全管理组件交互图
实现基于Spring框架应用的权限控制系统
图2
Acegi安全控制系统数据库设计

 

3、认证管理器,授权管理器的配置

  实现系统的安全控制,首先需要对系统的安全管理器和授权管理器进行配置,系统进行认证和授权需要获取安全信息,Acegi本身提供了对认证信息的获取机制,在实现认证与授权过程中,系统将主动根据配制信息和相应的信息解释安全信息的读取。图3给出了一个将用户安全信息存储在数据库中的认证管理器的配置示意图。

  对应于图示的XML配置文件的代码如下:




/* 配置数据库datasource 和Acegi 的 JDBCDao */
<bean id=”dataSource” class=”org.springFramework.jdbc.datasource.DriverManagerDataSource”>
 <property
name=”driverClassName”>
  <value>${jdbc.driverClassName}</value>
 </property>
 <property
name=”url”>
  <value>${jdbc.url}</value>
 </property>



 






实现基于Spring框架应用的权限控制系统
图3
认证管理器配制示意图



 




<property
name=”username”>
 <value>${jdbc.username}</value>
</property>
<property
name=”password”>
 <value>${jdbc.password}</value>
</property>
</bean>
<bean
id=”jdbcDaoImpl” class=”org.aceGISecurity. roviders. dao.jdbc.JdbcDaoImpl”>
 <property
name=”dataSource”>
  <ref
bean=”dataSource”/>
 </property>
</bean>

/*配置用户信息的加密算法*/
<bean
id=”passwordEncoder”
Class=”org.acegisecurity.providers.encoding.Md5passwordEncoder”/>
/*配置缓存有效时间*/
<bean
id=”userCache” class=”org.acegiSecurity. providers.
dao.cache.EhCacheBasedUserCache”>
 …//这里对缓存有效时间进行设置
</bean>

/*配置daoAuthenticationProvider*/
<bean
id=”daoAuthenticationProvider”

class=”org.acegisecurity.providers.dao.DaoAuthenticationProvider”>
 <property
name=”authenticationDao”>
  <ref
local=”JdbcDaoImpl”/>
 </property>
 <property
name=”passwordEncoder”>
  <ref local=”
passwordEncoder”/>
 </property>
 <property name=”userCache”>
  <ref
local=” userCache”/>
 </property>

</bean>

/*配置认证管理器*/
<bean
id=”authenticationManager” class=”org.acegisecurity.
providers.ProviderManager”>
 <property
name=”providers”>
  <list>
   <ref
local=”daoAuthenticationProvider”/>
  </list>
 </property>
</bean>


  授权管理器的配置方法与认证管理器的配置基本类似,这里不再讨论。

  4、安全请求拦截器的配置

  以上配置完成后,就需要配置安全拦截器。不同的安全管理对象需要使用不同的安全拦截器。对于方法级的安全认证需要使用的拦截器为MethodSecurityInterceptor,而应用于URL资源的安全拦截器为FilterSecurityInterceptor
。其中,MethodSecurityInterceptor拦截器是借助于Spring
Aop实现的,而FilterSecurityInterceptor拦截器是借助于Servlet Filter
实现的。本文以URL资源请求的安全拦截器为例说明配置情况。

  由于URL资源请求安全拦截是借助于过滤器进行的。因此首先要配置Acegi
Servlet过滤器。过滤器类似于AOP Around装备,实现在Web资源调用前后进行的一些操作6种过滤器,他们依次构成Servlet过滤器链,依次处理客户请求。需要注意的是过滤器配置的顺序是不能交换的,当不需要使用某个过滤器时,可直接将其删除和注释。过滤器在web.xml中配置形式为




<filter>
 <filter-name>Acegi HTTP Request Security
Filter</filter-name>
 <filter-class>org.acegisecurity.util.FilterToBeanProxy</filter-class>
 <init-param>
  <param-name>targetClass</param-name>
  <param-value>
   Org.acegisecurity.intercept.web.SecurityEnforcementFilter
  </param-value>
 </init-param>
</filter>
<filter-mapping>
 <filter-name>Acigi
HTTP Request Security
Filter</filter-name>
 <url-pattern>/*</url-pattern>
</filter-mapping>


  在spring
applicationContext.xml文件中的配置形式为




<bean id=”securityEnforcementFilter” class=””>
 <property
name=”filterSecurityInterceptor”>
  <ref
bean=”filterInvocationInteceptor”/>
 </property>
 <property
name=”authenticationEntryPoint”>
  <ref
bean=”authenticationProcessingFilterEntryPoint”/>
 </property>


  以上代码是SecurityEnforcementFilter的配置,该过滤器对用户是否有权访问web资源作出最后的决定。其它的过滤器的配置类同。
配置完过滤器后,需要对拦截器FilterSecurityInterceptor进行配置,




<bean id=”filterInvocationInterceptor”
Class=””>
 <property
name=”authenuserCacheticationManager”>1
 <property name=”AccessDecisionManager”>
 <property
name=”objectDefinitionSource”>
  <ref
local="filterObjectDefinitionSource"/>
 </property>
<bean
id="filterObjectDefinitionSource"
class="org.xiaohongli.acegi.db.DBFilterObjectDefinitionSource">
 <constructor-arg><refbean="jdbcTemplate"/>

 </constructor-arg>
</bean>


  objectDefinitionSource属性定义了那些受保护的URL资源,其中引用了一个本地对象filterObjectDefinitionSource。filterObjectDefinitionSource类从数据库中读取需要保护的URL安全信息,它扩展了PathBasedFilterInvocationDefinition
Map类。
同样,实现了另外一个methodObjectDefinitionSource类从数据库中读取需要保护的FUNCTION资源,它扩展了MethodDefinitionMap类。限于篇幅,在这里就不列出具体实现的源代码。




<bean
id="methodObjectDefinitionSource"
class="org.xiaohongli.acegi.db.DBMethodObjectDefinitionSource">
<constructor-arg><refbean="jdbcTemplate"/>

</constructor-arg>
</bean>


  结束语

  由于Spring在越来越多的项目中的应用,因此基于Spring应用的安全控制系统的研究就显得非常重要。Acegi提供了对Spring应用安全的支持,然而
Acegi本身提供的实例并不能满足大规模的复杂的权限需求,本文通过扩展Acegi的数据库设计即可满足复杂的权限需求。然而,怎样将Acegi应用到非Spring的系统中,还有待进一步研究。

 

© 著作权归作者所有

黄正文
粉丝 14
博文 25
码字总数 14020
作品 0
巴南
程序员
私信 提问
加载中

评论(1)

d
dizh
写的真不错。
使用vue集成spring security进行安全登陆

在前后端分离的状态下,传统的spring security认证模式也需要做一点改造,以适应ajax的前端访问模式 现在前后端分离的开发模式已经成为主流,好处不多说了,说说碰到的问题和坑。首先要解决的...

暴走的初号机
05/17
0
0
iBase4J-JAVA分布式Web系统

iBas4J项目简介 iBase4J是基于Java的开源框架搭建的分布式系统架构。 使用Maven对项目进行模块化管理,提高项目的易开发性、扩展性。 系统包括两个模块:系统管理模块、调度管理模块、Web展示...

iBase4J
2016/06/15
45
0
《Spring Boot极简教程》第16章 Spring Boot安全集成Spring Security

第16章 Spring Boot安全集成Spring Security 开发Web应用,对页面的安全控制通常是必须的。比如:对于没有访问权限的用户需要转到登录表单页面。要实现访问控制的方法多种多样,可以通过Aop...

程序员诗人
2017/04/17
0
0
新书上架:《Spring Boot 开发实战》(基于 Kotlin + Gradle + Spring Boot 2.0 的企业级服务端开发实战)

新书上架:《Spring Boot 开发实战》 — 基于 Kotlin + Gradle + Spring Boot 2.0 的企业级服务端开发实战 京东下单链接 https://item.jd.com/31178320122.html 天猫下单链接 https://detail...

程序员诗人
2018/08/05
0
0
新书上架:《Spring Boot 开发实战》基于 Kotlin + Gradle + Spring Boot 2.0 的企业级服务端开发实战

新书上架:《Spring Boot 开发实战》 — 基于 Kotlin + Gradle + Spring Boot 2.0 的企业级服务端开发实战 京东下单链接 https://item.jd.com/31178320122.html 天猫下单链接 https://detail...

程序员诗人
2018/08/22
0
0

没有更多内容

加载失败,请刷新页面

加载更多

009、Linux 文件权限管理

Linux 文件权限管理

北岩
28分钟前
5
0
Kafka学习笔记(三)—Kafka消息丢失,消费重复

一、数据传输事务的定义 最多一次(at most once):消息不会被重复发送,但是可能丢失 最少一次 (at least once)消息可能会被重复发送,但是不会漏发送 精确一次(exactly once) 不会少发...

Algoric
32分钟前
5
0
ajax设置请求头部时遇到的问题

w3c规定 当请求的header包含以下字段时 会被zhong'zhi Accept-Charset Accept-Encoding Connection Content-Length Cookie Cookie2 Content-Transfer-Encoding Date Expect Host Keep-Alive......

Bing309
56分钟前
5
0
总结:Linux

一、目录 目录 作用 /bin 存放二进制可执行文件(ls,cat,mkdir等),常用命令一般都在这里。 /etc /home 存放所有用户文件的根目录,是用户主目录的基点,比如用户user的主目录就是/home/user,...

浮躁的码农
59分钟前
4
0
什么是 happens-before 原则?

Java 中 happens-before 原则,是在 JSR-133 中提出的。 原文摘要: • Each action in a thread happens-before every subsequent action in that thread. • An unlock on a monitor happe......

ConstXiong
今天
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部