Results 1 to 10 of 10

Thread: EhCacheBasedUserCache - Where is it?

  1. #1
    Join Date
    Mar 2005
    Location
    Los Angeles
    Posts
    23

    Default 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. #2
    Join Date
    Aug 2004
    Location
    Sydney, Australia
    Posts
    2,768

    Default

    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.

  3. #3
    Join Date
    Mar 2005
    Location
    Los Angeles
    Posts
    23

    Default

    nm

  4. #4
    Join Date
    Mar 2005
    Location
    Los Angeles
    Posts
    23

    Default

    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?

  5. #5
    Join Date
    Mar 2005
    Location
    Los Angeles
    Posts
    23

    Default

    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>

  6. #6
    Join Date
    Aug 2004
    Location
    Sydney, Australia
    Posts
    2,768

    Default

    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.

  7. #7
    Join Date
    Sep 2004
    Location
    Boston, US
    Posts
    130

    Default

    The setCredentials method is not available in the Authentication interface.

    Any alternative way to accomplish the same.

    Thanks,
    Sanjiv

  8. #8
    Luke Taylor is offline Senior Member Acegi Security System TeamSpring Team
    Join Date
    Aug 2004
    Location
    Glasgow, Scotland
    Posts
    3,449

    Default

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

  9. #9
    Join Date
    Aug 2004
    Location
    Sydney, Australia
    Posts
    2,768

    Default

    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.
    Ben Alex
    Project Founder, Spring UAA, Spring Roo and Spring Security

  10. #10
    Join Date
    Sep 2004
    Location
    Boston, US
    Posts
    130

    Default

    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

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •