<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">

<beans>
<!-- filter chain -->
<bean id="filterChainProxy" class="org.acegisecurity.util.FilterChainProxy">
<property name="filterInvocationDefinitionSource">
<!--no filter: #TOKEN_NONE -->
<value><![CDATA[
CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
PATTERN_TYPE_APACHE_ANT
/**=concurrentSessionFilter,httpSessionContextIntegrationFilter,logoutFilter,authenticationProcessingFilter,rememberMeProcessingFilter,anonymousProcessingFilter,exceptionTranslationFilter,filterSecurityInterceptor
]]></value>
</property>
</bean>

<!-- filter -->
<!-- invalidate expired session and record last request time -->
<bean id="concurrentSessionFilter" class="sinosafecmb.web.security.ConcurrentSessionFilterModify">
<property name="sessionRegistry" ref="sessionRegistry"></property>
<property name="expiredUrl" value="/login.jsp?error=1"></property>
</bean>
<!-- create context in session and update that when response -->
<bean id="httpSessionContextIntegrationFilter" class="org.acegisecurity.context.HttpSessionContextIntegrationFilter">
<property name="forceEagerSessionCreation" value="true"></property>
</bean>

<!-- logout: /j_acegi_logout -->
<bean id="logoutFilter" class="org.acegisecurity.ui.logout.LogoutFilter">
<constructor-arg value="/login.jsp"/> <!-- URL redirected to after logout -->
<constructor-arg>
<list>
<ref bean="rememberMeServices"/> <!-- deleteCookie -->
<bean class="org.acegisecurity.ui.logout.SecurityContextLogoutHandler"/> <!-- invalidate session; clear context -->
</list>
</constructor-arg>
</bean>
<!-- login: j_username, j_password, /j_acegi_security_check, ACEGI_SECURITY_LAST_USERNAME(session)-->
<!-- fail: set exception in ACEGI_SECURITY_LAST_EXCEPTION_KEY(session) and redirect -->
<!-- success: set context and redirect -->
<bean id="authenticationProcessingFilter" class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilter">
<property name="authenticationManager" ref="authenticationManager"/> <!-- invoke to authenticate -->
<property name="authenticationFailureUrl" value="/login.jsp?error=3"/>
<property name="defaultTargetUrl" value="/login.do"/>
<property name="filterProcessesUrl" value="/j_acegi_security_check"/>
<property name="rememberMeServices" ref="rememberMeServices"/> <!-- success or fail to handle cookie-->
</bean>

<!-- auto login and authenticate -->
<!-- fail: delete cookie -->
<!-- success: set context -->
<bean id="rememberMeProcessingFilter" class="org.acegisecurity.ui.rememberme.RememberMeProcessingFilter">
<property name="rememberMeServices" ref="rememberMeServices"/> <!-- auto login -->
<property name="authenticationManager" ref="authenticationManager"/> <!-- invoke to authenticate -->
</bean>

<!-- anonymous login: clear authentication after request by default -->
<bean id="anonymousProcessingFilter" class="org.acegisecurity.providers.anonymous.AnonymousProcessingFilter">
<property name="key" value="changeThis"/> <!-- to identify if this object made by an authorised client -->
<property name="userAttribute" value="anonymous,ROLE_ANONYMOUS"/>
</bean>

<!-- handle exception -->
<!-- AuthenticationException: clear authentication and redirect to entry point -->
<!-- AccessDeniedException -->
<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"><!-- ACEGI_SECURITY_ACCESS_DENIED_EXCEPTION_KEY(request) -->
<property name="errorPage" value="/login.jsp?error=2"/>
</bean>
</property>
</bean>

<!-- authority -->
<bean id="filterSecurityInterceptor" class="org.acegisecurity.intercept.web.FilterSecurityInterceptor">
<property name="authenticationManager" ref="authenticationManager"/>
<property name="accessDecisionManager">
<bean class="org.acegisecurity.vote.AffirmativeBased">
<property name="allowIfAllAbstainDecisions" value="false"/>
<property name="decisionVoters">
<list>
<bean class="org.acegisecurity.vote.RoleVoter"/>
<bean class="org.acegisecurity.vote.AuthenticatedVoter"/>
</list>
</property>
</bean>
</property>
<property name="objectDefinitionSource">
<value><![CDATA[
PATTERN_TYPE_APACHE_ANT
/login.jsp=ROLE_ANONYMOUS,ROLE_ADMIN,ROLE_OPERATOR_DATA,
]]></value>
</property>
</bean>

<bean id="rememberMeServices" class="org.acegisecurity.ui.rememberme.TokenBasedRememberMeServices">
<property name="tokenValiditySeconds" value="1209600"/>
<property name="userDetailsService" ref="userDetailsService"/>
<property name="key" value="changeThis"/>
</bean>

<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>
<property name="sessionController"><ref bean="concurrentSessionController"/></property>
</bean>
<!-- concurrent session -->
<bean id="concurrentSessionController" class="org.acegisecurity.concurrent.ConcurrentSessionControllerImpl">
<property name="maximumSessions"><value>1</value></property>
<property name="sessionRegistry"><ref local="sessionRegistry"/></property>
</bean>
<bean id="sessionRegistry" class="org.acegisecurity.concurrent.SessionRegistryImpl"/>
<bean id="anonymousAuthenticationProvider" class="org.acegisecurity.providers.anonymous.AnonymousAuthenticationProvider">
<property name="key"><value>changeThis</value></property>
</bean>
<bean id="rememberMeAuthenticationProvider" class="org.acegisecurity.providers.rememberme.RememberMeAuthenticationProvider">
<property name="key"><value>changeThis</value></property>
</bean>
<bean id="daoAuthenticationProvider" class="org.acegisecurity.providers.dao.DaoAuthenticationProvider">
<property name="userDetailsService" ref="userDetailsService"/>
</bean>
<!-- data source -->
<bean id="huafademoDS"
class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName">
<value>java:huafademoDS</value>
</property>
<property name="jndiTemplate">
<ref bean="jndiTemplate"/>
</property>
</bean>
<!-- UserDetailsService is the most commonly frequently Acegi Security interface implemented by end users -->
<!--bean id="userDetailsService" class="org.acegisecurity.userdetails.memory.InMemoryDaoImpl">
<property name="userProperties">
<bean class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="location" value="/WEB-INF/users.properties"/>
</bean>
</property>
</bean-->
<bean id="userDetailsService" class="sinosafecmb.web.security.UserDetailsServiceProxy">
<property name="applicationController" ref="huafademoAC"/>
</bean>
<!-- bean id="userDetailsService" class="org.acegisecurity.userdetails.jdbc.JdbcDaoImpl">
<property name="dataSource"><ref bean="huafademoDS"/></property>
<property name="usersByUsernameQuery">
<value>SELECT c_user, c_password, 1 FROM zs_users WHERE c_user=?</value>
</property>
<property name="authoritiesByUsernameQuery">
<value>SELECT c_user, c_privilege FROM zs_authority WHERE c_user=?</value>
</property>
</bean-->

<!-- 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"/>
<!-- messages -->
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basename"><value>org/acegisecurity/messages</value></property>
</bean>

</bean>
</beans>
代码中加入了自己的注释,针对项目需要,对acegi做了几个修改。
1. 因为项目是分布式部署的,所以在页面的控制层中做了一个代理userDetailsService,用来从ejb中获得需要的数据。
2. 原来的acegi在控制同一用户登陆的时候有点小问题:被踢出去的用户session未超时,所以必须打开一个新窗口登陆。于是修改了concurrentSessionFilter中的代码,在踢用户的时候,让session失效