applicationContext-acegi-security.xml
1.[color=darkred]filterChainProxy[/color]配置
<bean id="filterChainProxy" class="org.acegisecurity.util.FilterChainProxy">
<property name="filterInvocationDefinitionSource">
<value>
CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
PATTERN_TYPE_APACHE_ANT
/**=httpSessionContextIntegrationFilter,logoutFilter,authenticationProcessingFilter,securityContextHolderAwareRequestFilter,rememberMeProcessingFilter,anonymousProcessingFilter,exceptionTranslationFilter,filterInvocationInterceptor
</value>
</property>
</bean>
2.[color=darkred]httpSessionContextIntegrationFilter[/color]配置
<bean id="httpSessionContextIntegrationFilter" class="org.acegisecurity.context.HttpSessionContextIntegrationFilter"/>
3.[color=darkred]logoutFilter[/color]配置
<bean id="logoutFilter" class="org.acegisecurity.ui.logout.LogoutFilter">
<constructor-arg value="/index.jsp"/> <!-- URL redirected to after logout -->
<constructor-arg>
<list>
<ref bean="rememberMeServices"/>
<bean class="org.acegisecurity.ui.logout.SecurityContextLogoutHandler"/>
</list>
</constructor-arg>
</bean>
4.[color=darkred]authenticationProcessingFilter[/color]配置
<bean id="authenticationProcessingFilter" class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilter">
<property name="authenticationManager" ref="authenticationManager"/>
<property name="authenticationFailureUrl" value="/login.jsp?login_error=1"/>
<property name="defaultTargetUrl" value="/"/>
<property name="filterProcessesUrl" value="/j_acegi_security_check"/>
<property name="rememberMeServices" ref="rememberMeServices"/>
</bean>
5.[color=darkred]securityContextHolderAwareRequestFilter[/color]配置
<bean id="securityContextHolderAwareRequestFilter" class="org.acegisecurity.wrapper.SecurityContextHolderAwareRequestFilter"/>
6.[color=darkred]rememberMeProcessingFilter[/color]配置
<bean id="rememberMeProcessingFilter" class="org.acegisecurity.ui.rememberme.RememberMeProcessingFilter">
<property name="authenticationManager" ref="authenticationManager"/>
<property name="rememberMeServices" ref="rememberMeServices"/>
</bean>
7.[color=darkred]anonymousProcessingFilter[/color]配置
<bean id="anonymousProcessingFilter" class="org.acegisecurity.providers.anonymous.AnonymousProcessingFilter">
<property name="key" value="changeThis"/>
<property name="userAttribute" value="anonymousUser,ROLE_ANONYMOUS"/>
</bean>
8.[color=darkred]exceptionTranslationFilter[/color]配置
<bean id="exceptionTranslationFilter" class="org.acegisecurity.ui.ExceptionTranslationFilter">
<property name="authenticationEntryPoint">
<bean class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilterEntryPoint">
<property name="loginFormUrl" value="/login.jsp"/>
<property name="forceHttps" value="false"/>
</bean>
</property>
<property name="accessDeniedHandler">
<bean class="org.acegisecurity.ui.AccessDeniedHandlerImpl">
<property name="errorPage" value="/accessDenied.jsp"/>
</bean>
</property>
</bean>
9.[color=darkred]filterInvocationInterceptor[/color]配置
<bean id="filterInvocationInterceptor" class="org.acegisecurity.intercept.web.FilterSecurityInterceptor">
<property name="authenticationManager" ref="authenticationManager"/>
<property name="accessDecisionManager" ref="accessDecisionManager"/>
<property name="objectDefinitionSource">
<value>
PATTERN_TYPE_APACHE_ANT
/mainFrame.html=admin,user
/文件夹1/*.html*=admin,user
/文件夹2/*.html*=admin,user
/文件夹3/*.html*=admin
/accessDenied.jsp*=ROLE_ANONYMOUS
</value>
</property>
</bean>
10.[color=darkred]accessDecisionManager[/color]配置
<bean id="accessDecisionManager" class="org.acegisecurity.vote.AffirmativeBased">
<property name="allowIfAllAbstainDecisions" value="false"/>
<property name="decisionVoters">
<list>
<bean class="org.acegisecurity.vote.RoleVoter">
<property name="rolePrefix" value=""/>
</bean>
<bean class="org.acegisecurity.vote.AuthenticatedVoter"/>
</list>
</property>
</bean>
11.[color=darkred]rememberMeServices[/color]配置
<bean id="rememberMeServices" class="org.acegisecurity.ui.rememberme.TokenBasedRememberMeServices">
<property name="userDetailsService" ref="userDetailsService"/>
<property name="key" value="changeThis"/>
</bean>
12.[color=darkred]authenticationManager[/color]配置
<bean id="authenticationManager" class="org.acegisecurity.providers.ProviderManager">
<property name="providers">
<list>
<ref local="daoAuthenticationProvider"/>
<bean class="org.acegisecurity.providers.anonymous.AnonymousAuthenticationProvider">
<property name="key" value="changeThis"/>
</bean>
<bean class="org.acegisecurity.providers.rememberme.RememberMeAuthenticationProvider">
<property name="key" value="changeThis"/>
</bean>
</list>
</property>
</bean>
13.[color=darkred]daoAuthenticationProvider[/color]配置
<bean id="daoAuthenticationProvider" class="org.acegisecurity.providers.dao.DaoAuthenticationProvider">
<property name="userDetailsService" ref="userDetailsService"/>
<property name="userCache">
<bean class="org.acegisecurity.providers.dao.cache.EhCacheBasedUserCache">
<property name="cache">
<bean class="org.springframework.cache.ehcache.EhCacheFactoryBean">
<property name="cacheManager">
<bean class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
<property name="configLocation" value="classpath:ehcache.xml"/>
</bean>
</property>
<property name="cacheName" value="userCache"/>
</bean>
</property>
</bean>
</property>
</bean>
14.[color=darkred]methodSecurityInterceptor[/color]配置
<bean id="methodSecurityInterceptor" class="org.acegisecurity.intercept.method.aopalliance.MethodSecurityInterceptor">
<property name="authenticationManager" ref="authenticationManager"/>
<property name="accessDecisionManager" ref="accessDecisionManager"/>
<property name="objectDefinitionSource">
<value>
com.rain.wsh.service.IUserService.get*=IS_AUTHENTICATED_ANONYMOUSLY
com.rain.wsh.service.IUserService.create*=IS_AUTHENTICATED_ANONYMOUSLY
com.rain.wsh.service.IUserService.update*=IS_AUTHENTICATED_ANONYMOUSLY
com.rain.wsh.service.IUserService.delete*=IS_AUTHENTICATED_ANONYMOUSLY
</value>
</property>
</bean>
15.[color=darkred]loggerListener[/color]配置
<!-- This bean is optional; it isn't used by any other bean as it only listens and logs -->
<bean id="loggerListener" class="org.acegisecurity.event.authentication.LoggerListener"/>
注:[color=darkred]userDetailsService[/color]定义为:
<bean id="userDetailsService" class="com.rain.wsh.service.impl.UserDetailsServiceImpl"/>
package com.rain.wsh.service.impl;
import org.acegisecurity.userdetails.UserDetails;
import org.acegisecurity.userdetails.[color=darkred]UserDetailsService[/color];
import org.acegisecurity.userdetails.UsernameNotFoundException;
import org.springframework.dao.DataAccessException;
import com.rain.wsh.dao.IUserDAO;
public class UserDetailsServiceImpl implements [color=darkred]UserDetailsService [/color]{
private final Logger log = Logger.getLogger(getClass());
private IUserDAO userDAO;
/**
* @return the userDAO
*/
public IUserDAO getUserDAO() {
return userDAO;
}
/**
* @param userDAO the userDAO to set
*/
public void setUserDAO(IUserDAO userDAO) {
this.userDAO = userDAO;
}
/*
* (non-Javadoc)
* @see org.acegisecurity.userdetails.UserDetailsService#loadUserByUsername(java.lang.String)
*/
public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException, DataAccessException {
UserDetails user = userDAO.getUserByName(userName);
if (user == null) {
log.error("The user was not found:" + userName);
throw new UsernameNotFoundException("The user was not found:" + userName);
}
return user;
}
}
注意user必须实现Serializable, UserDetails
[color=darkred]二.配置顺序[/color]
在web.xml中定义的filter的顺序是非常重要的。不管你实际用到哪个filter,<filter-mapping>的顺序应该是如下所示的:
1.ChannelProcessingFilter,因为可能要重定向到另一种协议。
2.ConcurrentSessionFilter 因为不使用任何SecurityContextHolder的功能,但是需要更新SessionRegistry来表示当前的发送请求的principal。
3. HttpSessionContextIntegrationFilter, 这样当一个web请求开始的时候就可以在SecurityContextHolder中设置一个SecurityContext,当web请求结束的时候任何对SecurityContext的改动都会被copy到HttpSession(以备下一个web请求使用)。
4.Authentication processing mechanisms - AuthenticationProcessingFilter, CasProcessingFilter, BasicProcessingFilter, HttpRequestIntegrationFilter, JbossIntegrationFilter 等 - 修改SecurityContextHolder,使其中包含一个有效的认证请求令牌(token)。
5.SecurityContextHolderAwareRequestFilter, 如果你使用它来在你的servlet容器中安装一个Acegi Security aware HttpServletRequestWrapper。
6.RememberMeProcessingFilter, 如果早期的认证处理过程没有更新SecurityContextHolder,并且请求(request)提供了一个cookie启用remember-me服务,一个合适的被记住的Authentication对象会被放到SecurityContextHolder那里。
7.AnonymousProcessingFilter, 如果早期的认证处理过程没有更新SecurityContextHolder,, 一个匿名Authentication 对象会被放到SecurityContextHolder那里。
8.ExceptionTranslationFilter, 捕获所有的Acegi Security 异常,这样要么返回一个HTTP错误响应或者加载一个对应的AuthenticationEntryPoint。
9.FilterSecurityInterceptor, 保护 web URIs
所有上述的filter使用FilterToBeanProxy或FilterChainProxy。建议在一个应用中使用一个单个的FilterToBeanProxy代理到一个单个的FilterChainProxy。,在FilterChainProxy中定义所有的Acegi Security Filters。如果你使用SiteMesh,确保Acegi Security filters 在 SiteMesh filters调用前调用。这样使SecurityContextHolder在SiteMesh decorator使用前能够及时被装配。
1.[color=darkred]filterChainProxy[/color]配置
<bean id="filterChainProxy" class="org.acegisecurity.util.FilterChainProxy">
<property name="filterInvocationDefinitionSource">
<value>
CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
PATTERN_TYPE_APACHE_ANT
/**=httpSessionContextIntegrationFilter,logoutFilter,authenticationProcessingFilter,securityContextHolderAwareRequestFilter,rememberMeProcessingFilter,anonymousProcessingFilter,exceptionTranslationFilter,filterInvocationInterceptor
</value>
</property>
</bean>
2.[color=darkred]httpSessionContextIntegrationFilter[/color]配置
<bean id="httpSessionContextIntegrationFilter" class="org.acegisecurity.context.HttpSessionContextIntegrationFilter"/>
3.[color=darkred]logoutFilter[/color]配置
<bean id="logoutFilter" class="org.acegisecurity.ui.logout.LogoutFilter">
<constructor-arg value="/index.jsp"/> <!-- URL redirected to after logout -->
<constructor-arg>
<list>
<ref bean="rememberMeServices"/>
<bean class="org.acegisecurity.ui.logout.SecurityContextLogoutHandler"/>
</list>
</constructor-arg>
</bean>
4.[color=darkred]authenticationProcessingFilter[/color]配置
<bean id="authenticationProcessingFilter" class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilter">
<property name="authenticationManager" ref="authenticationManager"/>
<property name="authenticationFailureUrl" value="/login.jsp?login_error=1"/>
<property name="defaultTargetUrl" value="/"/>
<property name="filterProcessesUrl" value="/j_acegi_security_check"/>
<property name="rememberMeServices" ref="rememberMeServices"/>
</bean>
5.[color=darkred]securityContextHolderAwareRequestFilter[/color]配置
<bean id="securityContextHolderAwareRequestFilter" class="org.acegisecurity.wrapper.SecurityContextHolderAwareRequestFilter"/>
6.[color=darkred]rememberMeProcessingFilter[/color]配置
<bean id="rememberMeProcessingFilter" class="org.acegisecurity.ui.rememberme.RememberMeProcessingFilter">
<property name="authenticationManager" ref="authenticationManager"/>
<property name="rememberMeServices" ref="rememberMeServices"/>
</bean>
7.[color=darkred]anonymousProcessingFilter[/color]配置
<bean id="anonymousProcessingFilter" class="org.acegisecurity.providers.anonymous.AnonymousProcessingFilter">
<property name="key" value="changeThis"/>
<property name="userAttribute" value="anonymousUser,ROLE_ANONYMOUS"/>
</bean>
8.[color=darkred]exceptionTranslationFilter[/color]配置
<bean id="exceptionTranslationFilter" class="org.acegisecurity.ui.ExceptionTranslationFilter">
<property name="authenticationEntryPoint">
<bean class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilterEntryPoint">
<property name="loginFormUrl" value="/login.jsp"/>
<property name="forceHttps" value="false"/>
</bean>
</property>
<property name="accessDeniedHandler">
<bean class="org.acegisecurity.ui.AccessDeniedHandlerImpl">
<property name="errorPage" value="/accessDenied.jsp"/>
</bean>
</property>
</bean>
9.[color=darkred]filterInvocationInterceptor[/color]配置
<bean id="filterInvocationInterceptor" class="org.acegisecurity.intercept.web.FilterSecurityInterceptor">
<property name="authenticationManager" ref="authenticationManager"/>
<property name="accessDecisionManager" ref="accessDecisionManager"/>
<property name="objectDefinitionSource">
<value>
PATTERN_TYPE_APACHE_ANT
/mainFrame.html=admin,user
/文件夹1/*.html*=admin,user
/文件夹2/*.html*=admin,user
/文件夹3/*.html*=admin
/accessDenied.jsp*=ROLE_ANONYMOUS
</value>
</property>
</bean>
10.[color=darkred]accessDecisionManager[/color]配置
<bean id="accessDecisionManager" class="org.acegisecurity.vote.AffirmativeBased">
<property name="allowIfAllAbstainDecisions" value="false"/>
<property name="decisionVoters">
<list>
<bean class="org.acegisecurity.vote.RoleVoter">
<property name="rolePrefix" value=""/>
</bean>
<bean class="org.acegisecurity.vote.AuthenticatedVoter"/>
</list>
</property>
</bean>
11.[color=darkred]rememberMeServices[/color]配置
<bean id="rememberMeServices" class="org.acegisecurity.ui.rememberme.TokenBasedRememberMeServices">
<property name="userDetailsService" ref="userDetailsService"/>
<property name="key" value="changeThis"/>
</bean>
12.[color=darkred]authenticationManager[/color]配置
<bean id="authenticationManager" class="org.acegisecurity.providers.ProviderManager">
<property name="providers">
<list>
<ref local="daoAuthenticationProvider"/>
<bean class="org.acegisecurity.providers.anonymous.AnonymousAuthenticationProvider">
<property name="key" value="changeThis"/>
</bean>
<bean class="org.acegisecurity.providers.rememberme.RememberMeAuthenticationProvider">
<property name="key" value="changeThis"/>
</bean>
</list>
</property>
</bean>
13.[color=darkred]daoAuthenticationProvider[/color]配置
<bean id="daoAuthenticationProvider" class="org.acegisecurity.providers.dao.DaoAuthenticationProvider">
<property name="userDetailsService" ref="userDetailsService"/>
<property name="userCache">
<bean class="org.acegisecurity.providers.dao.cache.EhCacheBasedUserCache">
<property name="cache">
<bean class="org.springframework.cache.ehcache.EhCacheFactoryBean">
<property name="cacheManager">
<bean class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
<property name="configLocation" value="classpath:ehcache.xml"/>
</bean>
</property>
<property name="cacheName" value="userCache"/>
</bean>
</property>
</bean>
</property>
</bean>
14.[color=darkred]methodSecurityInterceptor[/color]配置
<bean id="methodSecurityInterceptor" class="org.acegisecurity.intercept.method.aopalliance.MethodSecurityInterceptor">
<property name="authenticationManager" ref="authenticationManager"/>
<property name="accessDecisionManager" ref="accessDecisionManager"/>
<property name="objectDefinitionSource">
<value>
com.rain.wsh.service.IUserService.get*=IS_AUTHENTICATED_ANONYMOUSLY
com.rain.wsh.service.IUserService.create*=IS_AUTHENTICATED_ANONYMOUSLY
com.rain.wsh.service.IUserService.update*=IS_AUTHENTICATED_ANONYMOUSLY
com.rain.wsh.service.IUserService.delete*=IS_AUTHENTICATED_ANONYMOUSLY
</value>
</property>
</bean>
15.[color=darkred]loggerListener[/color]配置
<!-- This bean is optional; it isn't used by any other bean as it only listens and logs -->
<bean id="loggerListener" class="org.acegisecurity.event.authentication.LoggerListener"/>
注:[color=darkred]userDetailsService[/color]定义为:
<bean id="userDetailsService" class="com.rain.wsh.service.impl.UserDetailsServiceImpl"/>
package com.rain.wsh.service.impl;
import org.acegisecurity.userdetails.UserDetails;
import org.acegisecurity.userdetails.[color=darkred]UserDetailsService[/color];
import org.acegisecurity.userdetails.UsernameNotFoundException;
import org.springframework.dao.DataAccessException;
import com.rain.wsh.dao.IUserDAO;
public class UserDetailsServiceImpl implements [color=darkred]UserDetailsService [/color]{
private final Logger log = Logger.getLogger(getClass());
private IUserDAO userDAO;
/**
* @return the userDAO
*/
public IUserDAO getUserDAO() {
return userDAO;
}
/**
* @param userDAO the userDAO to set
*/
public void setUserDAO(IUserDAO userDAO) {
this.userDAO = userDAO;
}
/*
* (non-Javadoc)
* @see org.acegisecurity.userdetails.UserDetailsService#loadUserByUsername(java.lang.String)
*/
public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException, DataAccessException {
UserDetails user = userDAO.getUserByName(userName);
if (user == null) {
log.error("The user was not found:" + userName);
throw new UsernameNotFoundException("The user was not found:" + userName);
}
return user;
}
}
注意user必须实现Serializable, UserDetails
[color=darkred]二.配置顺序[/color]
在web.xml中定义的filter的顺序是非常重要的。不管你实际用到哪个filter,<filter-mapping>的顺序应该是如下所示的:
1.ChannelProcessingFilter,因为可能要重定向到另一种协议。
2.ConcurrentSessionFilter 因为不使用任何SecurityContextHolder的功能,但是需要更新SessionRegistry来表示当前的发送请求的principal。
3. HttpSessionContextIntegrationFilter, 这样当一个web请求开始的时候就可以在SecurityContextHolder中设置一个SecurityContext,当web请求结束的时候任何对SecurityContext的改动都会被copy到HttpSession(以备下一个web请求使用)。
4.Authentication processing mechanisms - AuthenticationProcessingFilter, CasProcessingFilter, BasicProcessingFilter, HttpRequestIntegrationFilter, JbossIntegrationFilter 等 - 修改SecurityContextHolder,使其中包含一个有效的认证请求令牌(token)。
5.SecurityContextHolderAwareRequestFilter, 如果你使用它来在你的servlet容器中安装一个Acegi Security aware HttpServletRequestWrapper。
6.RememberMeProcessingFilter, 如果早期的认证处理过程没有更新SecurityContextHolder,并且请求(request)提供了一个cookie启用remember-me服务,一个合适的被记住的Authentication对象会被放到SecurityContextHolder那里。
7.AnonymousProcessingFilter, 如果早期的认证处理过程没有更新SecurityContextHolder,, 一个匿名Authentication 对象会被放到SecurityContextHolder那里。
8.ExceptionTranslationFilter, 捕获所有的Acegi Security 异常,这样要么返回一个HTTP错误响应或者加载一个对应的AuthenticationEntryPoint。
9.FilterSecurityInterceptor, 保护 web URIs
所有上述的filter使用FilterToBeanProxy或FilterChainProxy。建议在一个应用中使用一个单个的FilterToBeanProxy代理到一个单个的FilterChainProxy。,在FilterChainProxy中定义所有的Acegi Security Filters。如果你使用SiteMesh,确保Acegi Security filters 在 SiteMesh filters调用前调用。这样使SecurityContextHolder在SiteMesh decorator使用前能够及时被装配。