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

<!--
  - Application context containing authentication, channel
  - security and web URI beans.
  -
  - Only used by "filter" artifact.
  -
  - $Id: applicationContext-acegi-security.xml 1425 2006-04-28 06:43:50Z benalex $
  -->

<beans>

   <!-- ======================== FILTER CHAIN ======================= -->

	<!--  if you wish to use channel security, add "channelProcessingFilter," in front
	      of "httpSessionContextIntegrationFilter" in the list below -->
	<bean id="filterChainProxy" class="org.acegisecurity.util.FilterChainProxy">
      <property name="filterInvocationDefinitionSource">
         <value><![CDATA[
		    CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
		    PATTERN_TYPE_APACHE_ANT
            /**=httpSessionContextIntegrationFilter,logoutFilter,authenticationProcessingFilter,basicProcessingFilter,securityContextHolderAwareRequestFilter,rememberMeProcessingFilter,anonymousProcessingFilter,switchUserProcessingFilter,exceptionTranslationFilter,filterInvocationInterceptor
         ]]></value>
      </property>
    </bean>

   <!-- ======================== AUTHENTICATION ======================= -->

   <bean id="authenticationManager" class="org.acegisecurity.providers.ProviderManager">
      <property name="providers">
         <list>
            <ref local="daoAuthenticationProvider"/>
            <ref local="anonymousAuthenticationProvider"/>
             <ref local="rememberMeAuthenticationProvider"/>
         </list>
      </property>
   </bean>

   <bean id="jdbcDaoImpl" class="org.acegisecurity.userdetails.jdbc.JdbcDaoImpl">
      <property name="dataSource"><ref bean="dataSource"/></property>
   </bean>

   <bean id="passwordEncoder" class="org.acegisecurity.providers.encoding.Md5PasswordEncoder"/>

   <bean id="daoAuthenticationProvider" class="org.acegisecurity.providers.dao.DaoAuthenticationProvider">
      <property name="userDetailsService"><ref local="jdbcDaoImpl"/></property>
<!--      <property name="userCache"><ref local="userCache"/></property> -->
      <property name="passwordEncoder"><ref local="passwordEncoder"/></property>
   </bean>
<!--
   <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"/>

   <bean id="userCacheBackend" class="org.springframework.cache.ehcache.EhCacheFactoryBean">
      <property name="cacheManager">
         <ref local="cacheManager"/>
      </property>
      <property name="cacheName">
         <value>userCache</value>
      </property>
   </bean>

   <bean id="userCache" class="org.acegisecurity.providers.dao.cache.EhCacheBasedUserCache">
      <property name="cache"><ref local="userCacheBackend"/></property>
   </bean>
-->
   <!-- Automatically receives AuthenticationEvent messages -->
   <bean id="loggerListener" class="org.acegisecurity.event.authentication.LoggerListener"/>

   <bean id="basicProcessingFilter" class="org.acegisecurity.ui.basicauth.BasicProcessingFilter">
      <property name="authenticationManager"><ref local="authenticationManager"/></property>
      <property name="authenticationEntryPoint"><ref local="basicProcessingFilterEntryPoint"/></property>
   </bean>

   <bean id="basicProcessingFilterEntryPoint" class="org.acegisecurity.ui.basicauth.BasicProcessingFilterEntryPoint">
      <property name="realmName"><value>Contacts Realm</value></property>
   </bean>

   <bean id="anonymousProcessingFilter" class="org.acegisecurity.providers.anonymous.AnonymousProcessingFilter">
      <property name="key"><value>foobar</value></property>
      <property name="userAttribute"><value>anonymousUser,ROLE_ANONYMOUS</value></property>
   </bean>

   <bean id="anonymousAuthenticationProvider" class="org.acegisecurity.providers.anonymous.AnonymousAuthenticationProvider">
      <property name="key"><value>foobar</value></property>
   </bean>

   <bean id="httpSessionContextIntegrationFilter" class="org.acegisecurity.context.HttpSessionContextIntegrationFilter">
   </bean>

   <bean id="rememberMeProcessingFilter" class="org.acegisecurity.ui.rememberme.RememberMeProcessingFilter">
      <property name="authenticationManager"><ref local="authenticationManager"/></property>
      <property name="rememberMeServices"><ref local="rememberMeServices"/></property>
   </bean>

   <bean id="rememberMeServices" class="org.acegisecurity.ui.rememberme.TokenBasedRememberMeServices">
      <property name="userDetailsService"><ref local="jdbcDaoImpl"/></property>
      <property name="key"><value>springRocks</value></property>
   </bean>

   <bean id="rememberMeAuthenticationProvider" class="org.acegisecurity.providers.rememberme.RememberMeAuthenticationProvider">
      <property name="key"><value>springRocks</value></property>
   </bean>

   <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>

   <bean id="securityContextHolderAwareRequestFilter" class="org.acegisecurity.wrapper.SecurityContextHolderAwareRequestFilter"/>

   <!-- ===================== HTTP CHANNEL REQUIREMENTS ==================== -->

   <!-- You will need to uncomment the "Acegi Channel Processing Filter"
        <filter-mapping> in web.xml for the following beans to be used -->

   <bean id="channelProcessingFilter" class="org.acegisecurity.securechannel.ChannelProcessingFilter">
      <property name="channelDecisionManager"><ref local="channelDecisionManager"/></property>
      <property name="filterInvocationDefinitionSource">
         <value><![CDATA[
			    CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
				\A/secure/.*\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="org.acegisecurity.securechannel.ChannelDecisionManagerImpl">
      <property name="channelProcessors">
         <list>
            <ref local="secureChannelProcessor"/>
            <ref local="insecureChannelProcessor"/>
         </list>
      </property>
   </bean>

   <bean id="secureChannelProcessor" class="org.acegisecurity.securechannel.SecureChannelProcessor"/>
   <bean id="insecureChannelProcessor" class="org.acegisecurity.securechannel.InsecureChannelProcessor"/>

   <!-- ===================== HTTP REQUEST SECURITY ==================== -->

   <bean id="exceptionTranslationFilter" class="org.acegisecurity.ui.ExceptionTranslationFilter">
      <property name="authenticationEntryPoint"><ref local="authenticationProcessingFilterEntryPoint"/></property>
      <property name="accessDeniedHandler">
      	<bean class="org.acegisecurity.ui.AccessDeniedHandlerImpl">
      		<property name="errorPage" value="/accessDenied.jsp"/>
      	</bean>
      </property>
   </bean>

   <bean id="authenticationProcessingFilter" class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilter">
      <property name="authenticationManager"><ref bean="authenticationManager"/></property>
      <property name="authenticationFailureUrl"><value>/acegilogin.jsp?login_error=1</value></property>
      <property name="defaultTargetUrl"><value>/</value></property>
      <property name="filterProcessesUrl"><value>/j_acegi_security_check</value></property>
      <property name="rememberMeServices"><ref local="rememberMeServices"/></property>
   </bean>

   <bean id="authenticationProcessingFilterEntryPoint" class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilterEntryPoint">
      <property name="loginFormUrl"><value>/acegilogin.jsp</value></property>
      <property name="forceHttps"><value>false</value></property>
   </bean>

   <bean id="httpRequestAccessDecisionManager" class="org.acegisecurity.vote.AffirmativeBased">
      <property name="allowIfAllAbstainDecisions"><value>false</value></property>
      <property name="decisionVoters">
         <list>
            <ref bean="roleVoter"/>
         </list>
      </property>
   </bean>

   <!-- Note the order that entries are placed against the objectDefinitionSource is critical.
        The FilterSecurityInterceptor will work from the top of the list down to the FIRST pattern that matches the request URL.
        Accordingly, you should place MOST SPECIFIC (ie a/b/c/d.*) expressions first, with LEAST SPECIFIC (ie a/.*) expressions last -->
   <bean id="filterInvocationInterceptor" class="org.acegisecurity.intercept.web.FilterSecurityInterceptor">
      <property name="authenticationManager"><ref bean="authenticationManager"/></property>
      <property name="accessDecisionManager"><ref local="httpRequestAccessDecisionManager"/></property>
      <property name="objectDefinitionSource">
         <value><![CDATA[
			    CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
			    PATTERN_TYPE_APACHE_ANT
			    /index.jsp=ROLE_ANONYMOUS,ROLE_USER
			    /hello.htm=ROLE_ANONYMOUS,ROLE_USER
			    /logoff.jsp=ROLE_ANONYMOUS,ROLE_USER
			    /switchuser.jsp=ROLE_SUPERVISOR
			    /j_acegi_switch_user=ROLE_SUPERVISOR
			    /acegilogin.jsp*=ROLE_ANONYMOUS,ROLE_USER
				/**=ROLE_USER
         ]]></value>
      </property>
   </bean>

   <!-- Filter used to switch the user context. Note: the switch and exit url must be secured
        based on the role granted the ability to 'switch' to another user -->
   <!-- In this example 'marissa' has ROLE_SUPERVISOR that can switch to regular ROLE_USER(s) -->
   <bean id="switchUserProcessingFilter" class="org.acegisecurity.ui.switchuser.SwitchUserProcessingFilter">
      <property name="userDetailsService" ref="jdbcDaoImpl" />
	  <property name="switchUserUrl"><value>/j_acegi_switch_user</value></property>
	  <property name="exitUserUrl"><value>/j_acegi_exit_user</value></property>
	  <property name="targetUrl"><value>/acegi-security-sample-contacts-filter/secure/index.htm</value></property>
   </bean>

</beans>
