基于Spring框架应用的权限控制系统的研究和实现
摘 要: 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安全框架介绍
2.1 spring 框架
Spring框架是由Open Source开发的一个优秀的多层J2EE系统框架,它为企业级应用提供了一个非常轻量级的解决方案,大大地降低了应用开发的难度与复杂度,提高了开发的速度。
Spring框架的核心是IoC和AOP。IoC是一种设计模式,即IoC模式。IoC模式进一步降低了类之间的耦合度,并且改变了传统的对象的创建方法,实现了一种配置式的对象管理方式,Spring框架中由IoC容器负责配置性的对象的管理。IoC模式极大的提高了系统开发与维护的灵活性。
AOP是一种编程模式,它是从系统的横切面关注问题。传统的面向对象编程OOP主要从系统的垂直切面对问题进行关注,对于系统的横切面关注很少,或者说很难关注,这样当考虑到系统的安全性、日志、事务以及其他企业级服务时,OOP就无能为力了,只能在所有相关类中加入类似的系统服务级的代码。AOP为解决系统级服务问题提供了一种很好的方法。AOP将系统服务分解成方面看待,并为类提供一种声明式系统服务方式。Java类不需要知道日志服务的存在也不需要考虑相关的代码。所以,用AOP编写的应用程序是松耦合的,代码的复用性就提高了。
2.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框架的系统中的应用
3.1 分析系统安全性需求
首先,需要明确进行安全控制的对象,可为业务方法和URL资源。
其次,需要进一步明确,系统身份认证资料和资源授权信息的数据持久化形式。
3.2 Acegi安全系统数据库设计
在Acegi框架中支持多种安全信息的持久化方式,可以在配置文件中配置或存放在关系数据库。由于在实际应用中,需求是经常发生变化的。所以,在配置文件中配置是满足不了实际应用需求的。然而,Acegi本身对权限表的设计非常简单,users表{username,password,enabled} 和authorities表{username,authority},这样简单的设计肯定无法适用复杂的权限需求。为了解决权限管理的复杂性,在这里引入了role(角色)的概念,使得用户和权限分离,一个用户拥有多个角色,一个角色拥有多个相应的权限,这样就更灵活地支持安全策略。
同时,为了更好地配合Acegi安全框架,还引入resource(资源)的概念,资源可分为URL和FUNCTION(方法)两种,一个权限可以对应多个资源。具体的数据库设计见图2。
3.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>
<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>
授权管理器的配置方法与认证管理器的配置基本类似,这里不再讨论。
3.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的系统中,还有待进一步研究。
苏先生ii:专注于Java开发技术的研究与知识分享!
————END————

基于Spring框架应用的权限控制系统的研究和实现的更多相关文章
- 基于Spring框架的简单多数据源切换解决办法
基于Spring框架的简单多数据源切换解决办法 Spring框架JDBC包提供了一个抽象类AbstractRoutingDataSource提供了动态切换数据库的基础方法.我们仅仅需要实现一个简单的数 ...
- 第一次玩博客,今天被安利了一个很方便JDBC的基于Spring框架的一个叫SimpleInsert的类,现在就来简单介绍一下
首先先对这段代码的简单介绍,我之前在需要操作JDBC的时候总是会因为经常要重新写SQL语句感到很麻烦.所以就能拿则拿不能拿的就简单地封装了一下. 首先是Insert.Spring框架的JDBC包里面的 ...
- 基于spring框架的apache shiro简单集成
关于项目的安全保护,我一直想找一个简单配置就能达到目的的方法,自从接触了shiro,这个目标总算达成了,以下结合我使用shiro的经验,谈谈比较轻便地集成该功能. 首先我们先了解一下shiro是什么. ...
- 使用NetBeans搭建基于Spring框架的Web应用
NetBeans下载链接:https://netbeans.org/. 第一步:选择“文件”菜单下的“新建项目”: 第二步:类别选择“Java Web”,项目选择“Web应用程序”,单击“下一步”: ...
- 基于Spring框架的Web应用开发笔记 - Outline
Motivation 最近的工作涉及Web框架搭建,在了解公司原有采用框架基础上对Web开发技术栈做了一次升级,在次做记录. Audience J2EE Web Application Develop ...
- 基于Spring AOP实现的权限控制
1.AOP简介 AOP,面向切面编程,往往被定义为促使软件系统实现关注点的分离的技术.系统是由许多不同的组件所组成的,每一个组件负责一块特定的功能.除了实现自身核心功能之外,这些组件还经常承担着额外的 ...
- 基于Spring框架怎么构建游戏玩法服务
说明:本篇阐述的问题,是基于前面的游戏服务器架构设计的. 问题 众所周知,Spring最擅长的领域是无状态服务的构建,而游戏(尤其是玩法部分)是有状态的.以棋牌游戏为例,玩法服务里面大概涉及以下两类对 ...
- 基于SSM框架的通用权限框架设计
1. 整体解决方案概述 1.1 权限整体解决方案概述 权限设计主要有一下几大部分组成: PassPort: 针对现在系统的分析,系统之间有部分信息是共享的,这部分信息将由 ...
- 基于Spring框架的Shiro配置
一.在web.xml中添加shiro过滤器 <!-- Shiro filter--> <filter> <filter-name>shiroFilter</ ...
随机推荐
- 渗透测试工具SQLmap
一.简介 SQLmap 是一款用 Python 编写的开源渗透测试工具,用来自动检测和利用 SQL 注入漏洞. 二.Windows 下安装 2.1 安装 Python 环境 注:Python 3.0会 ...
- leadcode的Hot100系列--62. 不同路径--简单的动态规划
题目比较清晰,简单来说就是: A B C D E F G H I J K L 只能往右或者往下,从A到L,能有几种走法. 这里使用动态规划的方法来做一下. 动态规划最重要的就是动态方程,这里简单说下这 ...
- CDH CM元数据梳理,包括HIVE
一.Schema SCM 表结构梳理(对应生产BAOFOO_SCM) AUDITS 登录信息.服务,角色重启.配置更改 PROCESSES 进程信息.这里面有很多信息.开放的web端口. HOST ...
- 记2017沈阳ICPC
2017沈阳ICPC 10月20日 早上十点抵达沈阳,趁着老师还没到,跑去故宫游玩了一下,玩到一点多回到宾馆,顺便吃了群里大佬说很好吃的喜家德虾饺(真的好好吃),回到宾馆后身体有点不舒服了,头晕晕的, ...
- Drools规则引擎-判断集合(List)是否包含集合
问题场景 在使用Drools规则引擎时,有朋友会遇到这样的问题,就是在when部分判断的两个参数都是集合类型,比如两个List,此时要判断一个集合是否包含另外一个集合的内容. 拿一个具体的例子来说明, ...
- WinForm控件之【DateTimePicker】
基本介绍 时间控件应用较为广泛,属性设置项也比较完善是非常好用的控件. 常设置属性.事件 CustomFormat:当Format属性设置为自定义类型时可自定义控件时间的显示格式: Enabled:指 ...
- DAX 第二篇:计算上下文
计算上下文是计算公式的环境,任何DAX表达式都是在上下文中求值的.行上下文和筛选上下文是DAX中仅有的上下文类型,把这两种上下文称为计算上下文.计算上下文用于限定公式计算的环境,当上下文变化时,相同的 ...
- Python入门基础(9)__面向对象编程_1
定义一个只包含方法的类 class 类名: def 方法1(self,参数列表): pass def 方法2(self,参数列表): pass 当一个类定义之后,要使用这个类来创键对象.语法如下: 对 ...
- C#3.0新增功能09 LINQ 标准查询运算符 01 概述
连载目录 [已更新最新开发文章,点击查看详细] 标准查询运算符 是组成 LINQ 模式的方法. 这些方法中的大多数都作用于序列:其中序列指其类型实现 IEnumerable<T> 接 ...
- [leetcode] 392. Is Subsequence (Medium)
原题 判断子序列 /** * @param {string} s * @param {string} t * @return {boolean} */ var isSubsequence = func ...