Announcement Announcement Module
Collapse
No announcement yet.
EhCacheBasedUserCache - Where is it? Page Title Module
Move Remove Collapse
This topic is closed
X
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • EhCacheBasedUserCache - Where is it?

    Where is the EhCacheBasedUserCache object stored at? When a user changes their password i need to remove the user from cache so that authentication knows to go back to the database to get their new password.

    thanks for any help

  • #2
    net.sf.acegisecurity.providers.dao.cache.EhCacheBa sedUserCache provides this capability out-of-the-box via its removeUserFromCache(String username) method.

    So you just need to use standard IoC principles to wire the bean which defines EhCacheBasedUserCache into your services layer (or web controller as applicable to your application architecture) which is responsible for coordinating the change password use case. A suggestion is a setUserCache(net.sf.acegisecurity.providers.dao.Us erCache) method, as the UserCache interface defines the remoteUserFromCache method. This gives you pluggability away from EH-CACHE-specific implementations.

    Comment


    • #3
      nm

      Comment


      • #4
        After I cleared the confusion from my head, I injected the UserCache object into my controllers who needed to reset the cached user. The cache gets cleared (or updated, i haven't decided which one is better to do yet) just fine. However, when the user goes to another page, the Principal object in the Authentication token still contains the old password, so the passwords never match and the user can not be authenticated. The user gets bumped to the login page (as configured) but it can't be authenticated, not even as an anonymous user (i guess because there is an authentication token available).

        This all happens after the user changes their own password then hits another page while still logged in the same session. Am I supposed to clear the authentication?

        Comment


        • #5
          I have configured the AuthenticationProcessingFilter to use NullRememberMeServices. I assume this means a user can not be authenticated based on the presence of a cookie. This is strange because if a user is logged in and I reload the application or restart Tomcat, the user is still authenticated. I am thinking this is the same reason why when a user has just changed their password, they are not able to view another secure page even if it allows ROLE_ANONYMOUS to view it.

          Does anybody have an idea what i can do to fix this?

          application context for acegi beans:

          Code:
          <?xml version="1.0" encoding="UTF-8"?>
          <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http&#58;//www.springframework.org/dtd/spring-beans.dtd">
          
          <beans>
          
              <description>
                  Contains the beans declarations for the acegi security system for spring objects.
              </description>
          	
          	<bean id="httpSessionContextIntegrationFilter" class="net.sf.acegisecurity.context.HttpSessionContextIntegrationFilter">
          		<property name="context"><value>net.sf.acegisecurity.context.security.SecureContextImpl</value></property>
          	</bean>
          
          
          	<bean id="authenticationProcessingFilter" class="com.ccg.security.CcgAuthenticationProcessingFilter">
          		<property name="authenticationManager"><ref bean="authenticationManager"/></property>
          		<property name="rememberMeServices"><ref bean="rememberMeServices"/></property>
          		<property name="authenticationFailureUrl"><value>/signon.html?error=1</value></property>
          		<property name="defaultTargetUrl"><value>/client_select.html</value></property>
          		<property name="filterProcessesUrl"><value>/j_acegi_security_check</value></property>
          	</bean>
          	
          	<bean id="securityEnforcementFilter" class="net.sf.acegisecurity.intercept.web.SecurityEnforcementFilter">
          		<property name="filterSecurityInterceptor"><ref bean="filterInvocationInterceptor"/></property>
          		<property name="authenticationEntryPoint"><ref bean="authenticationEntryPoint"/></property>
          		<property name="authenticationTrustResolver"><ref bean="authenticationTrustResolver"/></property>
          	</bean>
          	
          	<bean id="authenticationEntryPoint"	class="net.sf.acegisecurity.ui.webapp.AuthenticationProcessingFilterEntryPoint">
          		<property name="loginFormUrl"><value>/signon.html</value></property>
          		<property name="forceHttps"><value>false</value></property>
          	</bean>
          	
          	<bean id="authenticationTrustResolver" class="net.sf.acegisecurity.AuthenticationTrustResolverImpl"/>
          
          <!-- remember me services should do nothing at this point -->
          	<bean id="rememberMeServices" class="net.sf.acegisecurity.ui.rememberme.NullRememberMeServices"/>
          
          
          <!-- Filter Invocation Interceptor -->
          	<bean id="filterInvocationInterceptor" class="net.sf.acegisecurity.intercept.web.FilterSecurityInterceptor">
          		<property name="authenticationManager"><ref bean="authenticationManager"/></property>
          		<property name="accessDecisionManager"><ref local="httpRequestAccessDecisionManager"/></property>
          		<!-- <property name="accessDecisionManager"><ref bean="accessDecisionManager"/></property> -->
          		<!-- <property name="runAsManager"><ref bean="runAsManager"/></property> -->
          		<property name="objectDefinitionSource">
          		<!--
          			Define secure access properties here 
          			 *Note&#58; top most properties overide bottom most
          		-->
          			<value>
          				CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
          				PATTERN_TYPE_APACHE_ANT
          				
          				/signon.html*=ROLE_USER,ROLE_ANONYMOUS
          				/welcome.html=ROLE_USER,ROLE_ANONYMOUS
          				/reference.html=ROLE_USER,ROLE_ANONYMOUS
          
          				/images/**=ROLE_USER,ROLE_ANONYMOUS
          				/styles/**=ROLE_USER,ROLE_ANONYMOUS
          				/scripts/**=ROLE_USER,ROLE_ANONYMOUS
          				
          				/**=ROLE_USER
          			</value>
          		</property>
          	</bean>
          	
          <!-- Authentication manager -->
          	<bean id="authenticationManager" class="net.sf.acegisecurity.providers.ProviderManager">
          		<property name="providers">
          			<list>
          				<ref bean="daoAuthenticationProvider"/>
          				<ref bean="anonymousAuthenticationProvider"/>
          			</list>
          		</property>
          	</bean>
          
          <!-- HTTP Request Access Decision Manager - Determiner for HTTP request access.  Right now, all we need is one vote to allow access. -->
          	<bean id="httpRequestAccessDecisionManager" class="net.sf.acegisecurity.vote.AffirmativeBased">
          		<property name="allowIfAllAbstainDecisions"><value>false</value></property>
          		<property name="decisionVoters">
          			<list>
          				<ref bean="roleVoter"/>
          			</list>
          		</property>
          	</bean>	
          	
          	<!-- Authorization Related Beans -->
          		<bean id="roleVoter" class="net.sf.acegisecurity.vote.RoleVoter"/>
          		
          	
          <!-- DAO Authentication Provider - Acesses data source to lookup on our user list -->
          	<bean id="daoAuthenticationProvider" class="net.sf.acegisecurity.providers.dao.DaoAuthenticationProvider">
          		<property name="authenticationDao"><ref bean="accountDAO"/></property>
          		<property name="userCache"><ref bean="userCache"/></property>
          		<!-- <property name="authenticationDao"><ref bean="inMemoryDaoImpl"/></property> -->
          		<!-- <property name="saltSource"><ref bean="saltSource"/></property> -->
          		<property name="passwordEncoder"><ref bean="passwordEncoder"/></property>
          	</bean>
          
          <!-- Authentication Caching -->	
          	<bean id="userCache" class="net.sf.acegisecurity.providers.dao.cache.EhCacheBasedUserCache">
          		<property name="cache"><ref local="userCacheBackend"/></property>
          	</bean>
          	
          		<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="cacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
          			<property name="configLocation"><value>classpath&#58;/ehcache-failsafe.xml</value></property>
          		</bean>
          	
          <!-- Anonymous user/role for public access -->	
          	<bean id="anonymousAuthenticationProvider"	class="net.sf.acegisecurity.providers.anonymous.AnonymousAuthenticationProvider">
          		<property name="key"><value>anonUser</value></property>
          	</bean>
          
          		<bean id="anonymousProcessingFilter" class="net.sf.acegisecurity.providers.anonymous.AnonymousProcessingFilter">
          			<property name="key"><value>anonUser</value></property>
          			<property name="userAttribute"><value>anonymousUser,ROLE_ANONYMOUS</value></property>
          		</bean>
          	
          
          <!-- MD5 Password Encryption -->
          	<bean id="passwordEncoder" class="net.sf.acegisecurity.providers.encoding.Md5PasswordEncoder"/>
          	
          </beans>

          Comment


          • #6
            Because Acegi Security reauthenticates a user each request, if the ContextHolder contains an Authentication.getCredentials() which does not match the [DAO or cache obtained] UserDetails.getPassword(), authentication will fail.

            Your eviction from the cache in your web controller is correct. You'll need to also do something like the following, after you evict from the cache:

            Code:
            SecureContext sc = SecureContextUtils.getSecureContext&#40;&#41;;
            Authentication auth = sc.getAuthentication&#40;&#41;;
            auth.setCredentials&#40;newPassword&#41;;
            sc.setAuthentication&#40;auth&#41;;
            ContextHolder.setContext&#40;sc&#41;;
            Subsequent web requests will then work seamlessly.

            Comment


            • #7
              The setCredentials method is not available in the Authentication interface.

              Any alternative way to accomplish the same.

              Thanks,
              Sanjiv

              Comment


              • #8
                Originally posted by sjivan
                The setCredentials method is not available in the Authentication interface.

                Any alternative way to accomplish the same.

                Thanks,
                Sanjiv
                You could either

                a) Replace the existing security context object with a new, modified one.
                b) Use your own authentication object and add a setCredentials method.

                Comment


                • #9
                  Option (a) is better, and is actually quite simple because the new Authentication need only contain the principal and credentials properties - at the first time a secure method is invoked, the remainder will be automatically populated by the AbstractSecurityInterceptor. You could also do it more eagerly if you wanted, by calling the AuthenticationManager with the authentication request object.

                  Comment


                  • #10
                    I've gone with option a) and its working well. As posted elsewhere in this forum, the code I'm using to do this is :

                    Code:
                    SecureContextImpl newContext = new SecureContextImpl&#40;&#41;;
                    newContext.setAuthentication&#40;new UsernamePasswordAuthenticationToken&#40;loginName, pwd&#41;&#41;;
                    ContextHolder.setContext&#40;newContext&#41;;
                    Thanks,
                    Sanjiv

                    Comment

                    Working...
                    X