简介
对于一个典型的Web应用,完善的认证和授权机制是必不可少的,在SpringFramework中,Juergen Hoeller提供的范例JPetStore给了一些这方面的介绍,但还远远不够,Acegi是一个专门为SpringFramework提供安全机制的项目,全称为Acegi Security System for Spring,当前版本为0.5.1,就其目前提供的功能,应该可以满足绝大多数应用的需求。
本文的主要目的是希望能够说明如何在基于Spring构架的Web应用中使用Acegi,而不是详细介绍其中的每个接口、每个类。注意,即使对已经存在的Spring应用,通过下面介绍的步骤,也可以马上享受到Acegi提供的认证和授权。
基础工作
在你的Web应用的lib中添加Acegi下载包中的acegi-security.jar
web.xml
实现认证和授权的最常用的方法是通过filter,Acegi亦是如此,通常Acegi需要在web.xml添加以下5个filter:
<filter>
<filter-name>Acegi Channel Processing Filter</filter-name>
<filter-class>net.sf.acegisecurity.util.FilterToBeanProxy</filter-class>
<init-param>
<param-name>targetClass</param-name>
<param-value>net.sf.acegisecurity.securechannel.ChannelProcessingFilter</param-value>
</init-param>
</filter>
<filter>
<filter-name>Acegi Authentication Processing Filter</filter-name>
<filter-class>net.sf.acegisecurity.util.FilterToBeanProxy</filter-class>
<init-param>
<param-name>targetClass</param-name>
<param-value>net.sf.acegisecurity.ui.webapp.AuthenticationProcessingFilter</param-value>
</init-param>
</filter>
<filter>
<filter-name>Acegi HTTP BASIC Authorization Filter</filter-name>
<filter-class>net.sf.acegisecurity.util.FilterToBeanProxy</filter-class>
<init-param>
<param-name>targetClass</param-name>
<param-value>net.sf.acegisecurity.ui.basicauth.BasicProcessingFilter</param-value>
</init-param>
</filter>
<filter>
<filter-name>Acegi Security System for Spring Auto Integration Filter</filter-name>
<filter-class>net.sf.acegisecurity.ui.AutoIntegrationFilter</filter-class>
</filter>
<filter>
<filter-name>Acegi HTTP Request Security Filter</filter-name>
<filter-class>net.sf.acegisecurity.util.FilterToBeanProxy</filter-class>
<init-param>
<param-name>targetClass</param-name>
<param-value>net.sf.acegisecurity.intercept.web.SecurityEnforcementFilter</param-value>
</init-param>
</filter>
|
最先引起迷惑的是net.sf.acegisecurity.util.FilterToBeanProxy,Acegi自己的文档上解释是:“What FilterToBeanProxy does is delegate the Filter's methods through to a bean which is obtained from the Spring application context. This enables the bean to benefit from the Spring application context lifecycle support and configuration flexibility.”,如希望深究的话,去看看源代码应该不难理解。
再下来就是添加filter-mapping了:
<filter-mapping>
<filter-name>Acegi Channel Processing Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>Acegi Authentication Processing Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>Acegi HTTP BASIC Authorization Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>Acegi Security System for Spring Auto Integration Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>Acegi HTTP Request Security Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
|
这里,需要注意以下三点:
1) 这几个filter的顺序是不能更改的,顺序不对将无法正常工作;
2) 如果你的应用不需要安全传输,如https,则将"Acegi Channel Processing Filter"相关内容注释掉即可;
3) 如果你的应用不需要Spring提供的远程访问机制,如Hessian and Burlap,将"Acegi HTTP BASIC Authorization Filter"相关内容注释掉即可。
applicationContext.xml
接下来就是要添加applicationContext.xml中的内容了,从刚才FilterToBeanFactory的解释可以看出,真正的filter都在Spring的applicationContext中管理:
1)首先,你的数据库中必须具有保存用户名和密码的table,Acegi要求table的schema必须如下:
CREATE TABLE users (
username VARCHAR(50) NOT NULL PRIMARY KEY,
password VARCHAR(50) NOT NULL,
enabled BIT NOT NULL
);
CREATE TABLE authorities (
username VARCHAR(50) NOT NULL,
authority VARCHAR(50) NOT NULL
);
CREATE UNIQUE INDEX ix_auth_username ON authorities ( username, authority );
ALTER TABLE authorities ADD CONSTRAINT fk_authorities_users foreign key (username) REFERENCES users
(username);
|
2)添加访问你的数据库的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="net.sf.acegisecurity.providers.dao.jdbc.JdbcDaoImpl">
<property name="dataSource"><ref bean="dataSource"/></property>
</bean>
|
3)添加DaoAuthenticationProvider:
<bean id="daoAuthenticationProvider" class="net.sf.acegisecurity.providers.dao.DaoAuthenticationProvider">
<property name="authenticationDao"><ref bean="authenticationDao"/></property>
<property name="userCache"><ref bean="userCache"/></property>
</bean> <bean id="userCache" class="net.sf.acegisecurity.providers.dao.cache.EhCacheBasedUserCache">
<property name="minutesToIdle"><value>5</value></property>
</bean>
|
如果你需要对密码加密,则在daoAuthenticationProvider中加入:<property name="passwordEncoder"><ref bean="passwordEncoder"/></property>,Acegi提供了几种加密方法,详细情况可看包net.sf.acegisecurity.providers.encoding
4)添加authenticationManager:
<bean id="authenticationManager" class="net.sf.acegisecurity.providers.ProviderManager">
<property name="providers">
<list>
<ref bean="daoAuthenticationProvider"/>
</list>
</property>
</bean>
|
5)添加accessDecisionManager:
<bean id="accessDecisionManager" class="net.sf.acegisecurity.vote.AffirmativeBased">
<property name="allowIfAllAbstainDecisions">
<value>false</value>
</property>
<property name="decisionVoters">
<list><ref bean="roleVoter"/></list>
</property>
</bean>
<bean id="roleVoter" class="net.sf.acegisecurity.vote.RoleVoter"/>
|
6)添加authenticationProcessingFilterEntryPoint:
<bean id="authenticationProcessingFilterEntryPoint"
class="net.sf.acegisecurity.ui.webapp.AuthenticationProcessingFilterEntryPoint">
<property name="loginFormUrl"><value>/acegilogin.jsp</value></property>
<property name="forceHttps"><value>false</value></property>
</bean>
|
其中acegilogin.jsp是登陆页面,一个最简单的登录页面如下:
<%@ taglib prefix='c' uri='http://java.sun.com/jstl/core' %>
<%@ page import="net.sf.acegisecurity.ui.AbstractProcessingFilter" %>
<%@ page import="net.sf.acegisecurity.AuthenticationException" %>
<html>
<head>
<title>Login</title>
</head> <body>
<h1>Login</h1>
<form action="<c:url value='j_acegi_security_check'/>" method="POST">
<table>
<tr><td>User:</td><td><input type='text' name='j_username'></td></tr>
<tr><td>Password:</td><td><input type='password' name='j_password'></td></tr>
<tr><td colspan='2'><input name="submit" type="submit"></td></tr>
<tr><td colspan='2'><input name="reset" type="reset"></td></tr>
</table>
</form>
</body>
</html>
|
7)添加filterInvocationInterceptor:
<bean id="filterInvocationInterceptor"
class="net.sf.acegisecurity.intercept.web.FilterSecurityInterceptor">
<property name="authenticationManager">
<ref bean="authenticationManager"/>
</property>
<property name="accessDecisionManager">
<ref bean="accessDecisionManager"/>
</property>
<property name="objectDefinitionSource">
<value>
CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
\A/sec/administrator.*\Z=ROLE_SUPERVISOR
\A/sec/user.*\Z=ROLE_TELLER
</value>
</property>
</bean>
|
这里请注意,要objectDefinitionSource中定义哪些页面需要权限访问,需要根据自己的应用需求进行修改,我上面给出的定义的意思是这样的:
a. CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON意思是在比较请求路径时全部转换为小写
b. \A/sec/administrator.*\Z=ROLE_SUPERVISOR意思是只有权限为ROLE_SUPERVISOR才能访问/sec/administrator*的页面
c. \A/sec/user.*\Z=ROLE_TELLER意思是只有权限为ROLE_TELLER的用户才能访问/sec/user*的页面
8)添加securityEnforcementFilter:
<bean id="securityEnforcementFilter" class="net.sf.acegisecurity.intercept.web.SecurityEnforcementFilter">
<property name="filterSecurityInterceptor">
<ref bean="filterInvocationInterceptor"/>
</property>
<property name="authenticationEntryPoint">
<ref bean="authenticationProcessingFilterEntryPoint"/>
</property>
</bean>
|
9)添加authenticationProcessingFilter:
<bean id="authenticationProcessingFilter"
class="net.sf.acegisecurity.ui.webapp.AuthenticationProcessingFilter">
<property name="authenticationManager">
<ref bean="authenticationManager"/>
</property>
<property name="authenticationFailureUrl">
<value>/loginerror.jsp</value>
</property>
<property name="defaultTargetUrl">
<value>/</value>
</property>
<property name="filterProcessesUrl">
<value>/j_acegi_security_check</value>
</property>
</bean>
|
其中authenticationFailureUrl是认证失败的页面。
10)如果需要一些页面通过安全通道的话,添加下面的配置:
<bean id="channelProcessingFilter" class="net.sf.acegisecurity.securechannel.ChannelProcessingFilter">
<property name="channelDecisionManager">
<ref bean="channelDecisionManager"/>
</property>
<property name="filterInvocationDefinitionSource">
<value>
CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
\A/sec/administrator.*\Z=REQUIRES_SECURE_CHANNEL
\A/acegilogin.jsp.*\Z=REQUIRES_SECURE_CHANNEL
\A/j_acegi_security_check.*\Z=REQUIRES_SECURE_CHANNEL
\A.*\Z=REQUIRES_INSECURE_CHANNEL
</value>
</property>
</bean> <bean id="channelDecisionManager" class="net.sf.acegisecurity.securechannel.ChannelDecisionManagerImpl">
<property name="channelProcessors">
<list>
<ref bean="secureChannelProcessor"/>
<ref bean="insecureChannelProcessor"/>
</list>
</property>
</bean>
<bean id="secureChannelProcessor" class="net.sf.acegisecurity.securechannel.SecureChannelProcessor"/>
<bean id="insecureChannelProcessor" class="net.sf.acegisecurity.securechannel.InsecureChannelProcessor"/>
|
缺少了什么?
Acegi目前提供了两种“secure object”,分别对页面和方法进行安全认证管理,我这里介绍的只是利用FilterSecurityInterceptor对访问页面的权限控制,除此之外,Acegi还提供了另外一个Interceptor——MethodSecurityInterceptor,它结合runAsManager可实现对对象中的方法的权限控制,使用方法可参看Acegi自带的文档和contact范例。
最后要说的
本来以为只是说明如何使用Acegi而已,应该非常简单,但真正写起来才发现想要条理清楚的理顺所有需要的bean还是很困难的,但愿我没有遗漏太多东西,如果我的文章有什么遗漏或错误的话,还请参看Acegi自带的quick-start范例,但请注意,这个范例是不能直接拿来用的。
分享到:
相关推荐
### 基于Spring的Acegi安全框架认证与授权的分析及扩展 #### 1. Acegi安全框架的概述 Acegi(后更名为Spring ...通过本文档的介绍,希望能帮助读者更好地理解和运用Acegi安全框架,以构建更加健壮和安全的应用程序。
总的来说,"mypro.rar"项目展示了如何综合运用这些技术,构建一个具备用户登录认证、角色权限管理、数据权限控制功能的系统。通过Acegi的权限控制,我们可以限制不同角色对特定资源的访问;借助Spring,我们可以实现...
本文主要讨论的是如何在基于Spring框架的应用中实现权限控制系统,特别提到了Acegi安全框架的使用。Spring框架是一个流行的多层J2EE应用...在实际开发中,理解并熟练运用Acegi能够帮助构建更加健壮、安全的Web应用。
首先,用户权限管理是任何Web应用安全性的重要组成部分。AceGI通过定义安全拦截器(如FilterSecurityInterceptor)和访问决策管理者(如AccessDecisionManager)来处理这一问题。FilterSecurityInterceptor负责拦截...
在权限管理方面,Spring框架提供了一套强大的安全组件,称为Spring Security(原名Acegi Security)。这个组件允许我们实现用户认证(Authentication)和授权(Authorization)功能。用户认证涉及验证用户的身份,而...
随着Spring的发展,Acegi Security已经被Spring Security所取代,但理解Acegi在Spring中的运用对于学习Spring Security仍然有所帮助。 首先,让我们从"acegi.mysql.sql"开始。这个文件很可能是数据库脚本,用于创建...
Acegi 安全系统是专为基于 Spring 的应用设计的安全框架,它利用 Spring 的依赖注入和面向切面编程(AOP)能力来提供强大的安全保护。...理解并有效地运用Acegi,对于构建安全的Spring应用至关重要。
### Spring Security 安全权限管理手册 #### 一、为何选择 Spring Security? Spring Security 是一个强大的、高度可定制的身份验证和安全(授权)框架。它为应用提供了多种方式来实现安全性和权限管理,并且能够...
此外,Acegi Security还支持预授权和后授权策略,使得权限管理更加灵活。 三、会话管理 Acegi Security对会话进行了强化管理,可以防止会话劫持、会话固定攻击等。它提供了会话超时检测、会话固定保护(session-...
这个“acegi学习整理合集”包含了多个关于Acegi的讨论和教程,旨在帮助开发者深入理解并有效地运用Acegi进行应用的安全管理。 首先,"学习ACEGI - - New - JavaEye论坛.mht"可能是一个关于Acegi的入门教程,涵盖了...
在Java世界中,安全性和权限管理是构建任何企业级应用不可或缺的部分,Acegi为开发者提供了一种高效且灵活的方式来处理这些问题。 首先,"Acegi安全系统介绍.doc"文档很可能是对Acegi框架的基础概述,它可能涵盖了...
总的来说,"struts2+spring+hibernate实验设备管理系统"是一个综合运用了三大主流Java框架的实例,它展示了如何通过这些工具构建一个完整的、具备权限管理功能的管理系统。对这个系统的学习和研究,不仅可以加深对...
在权限管理中,Spring提供了强大的安全性支持,如Spring Security(原Acegi),可以实现用户的认证与授权,包括基于角色的访问控制(RBAC)和细粒度的权限分配。 Struts作为MVC框架,负责处理HTTP请求并将其映射到...
Acegi Security System for Spring(简称Acegi)是...实践中,应根据项目需求调整配置,灵活运用Acegi的各种组件,以达到最佳的安全效果。同时,不断学习和理解Acegi的原理,有助于更好地解决实际开发中的安全问题。
Acegi提供了一套全面的访问控制机制,包括身份验证、授权、会话管理以及基于角色的访问控制等功能,使得开发者能够更安全、更方便地管理应用的权限控制。 《Acegi教程.doc》可能是对Acegi框架的基础介绍,涵盖了...
以上就是关于"SSH集成Spring+hibernate+security 用户管理"项目的主要知识点,涵盖了Spring框架的依赖注入、Hibernate的ORM、Spring Security的权限控制,以及如何在实际项目中综合运用这些技术。这样的系统设计有助...
结合Spring Security进行权限管理,可以确保系统的安全性。这样的整合方案在大型企业级项目中非常常见,有助于提高代码质量、降低维护成本,并提升开发效率。在实际开发中,开发者需要深入理解这三个框架的核心概念...
Acegi(现在已被Spring Security替代)是一个强大的安全框架,提供认证、授权、会话管理等功能,确保应用程序的安全性。它可以集成到Spring框架中,提供细粒度的权限控制,保护应用程序免受未经授权的访问。 综合...
而Acegi插件则是Grails中用于权限管理和安全控制的重要组件,它借鉴了Spring Security(原名为Acegi Security)的核心理念,为Grails应用程序提供了强大的访问控制和身份验证功能。本文将详细介绍Grails Acegi 0.1...