Results 1 to 4 of 4

Thread: JdbcTokenRepositoryImpl not inserting persistant token

  1. #1
    Join Date
    Oct 2010
    Posts
    7

    Default JdbcTokenRepositoryImpl not inserting persistant token

    I im trying to use remember me function in a spring web flow app but the token is never inserted into the table persistent_logins.

    I am using spring 3.0.5, SWF 2.2.1 & spring security 3.0.5.

    I have created the table as per documentation and included <security:remember-me data-source-ref="dataSource"/> in my security config.

    I debugged the code and confirmed JdbcTokenRepositoryImpl is being called to insert the token, and checked log4j output to also confirm this. The update is executed using JdbcTemplate but it never commits and as far as I can see is not running within a transaction.

    I have taken the SQL its attempting to execute and ran manually which also works.

    Why is this not working?

  2. #2
    Join Date
    Oct 2010
    Posts
    7

    Default

    I fixed by making sure JdbcTokenRepositoryImpl executes within a transaction by using aop.

    Code:
    	<aop:config>
    		<aop:pointcut expression="execution(* org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl.*(..))"             id="rememberMeOperation"/>
    		<aop:advisor advice-ref="rememberMeTxAdvice" pointcut-ref="rememberMeOperation"/>
    	</aop:config>
    	
    	<tx:advice id="rememberMeTxAdvice" transaction-manager="transactionManager">
    		<tx:attributes>
    			<tx:method name="createNewToken"/>
    			<tx:method name="updateToken"/>
    			<tx:method name="removeUserTokens"/>
    		</tx:attributes>
    	</tx:advice>
    Not sure why a developer is required to do this? Isn't it obvious to Spring Security that a JDBC implementation needs to commit a transaction to database?

  3. #3
    Join Date
    Sep 2004
    Location
    Manchester, NH
    Posts
    1,236

    Default

    I would suspect that the answer depends on the data source that you have used to configure Spring Security. If you are using a transactional data source, then (IMO) it is you as the application designer who should dictate where transactional boundaries should be appropriately applied. Personally, I would rather that level of transactional control be in my hands than dictated arbitrarily by a framework designer (even though Luke is super smart)
    Peter Mularien | Blog
    Author, Spring Security 3 (Book) - Packt Publishing, Available in print and eBook form
    SCJP 5, Oracle DBA
    Any postings are my own opinion, and should not be attributed to my employer or clients.


  4. #4
    Join Date
    Oct 2010
    Posts
    7

    Default

    Quote Originally Posted by pmularien View Post
    I would suspect that the answer depends on the data source that you have used to configure Spring Security. If you are using a transactional data source, then (IMO) it is you as the application designer who should dictate where transactional boundaries should be appropriately applied. Personally, I would rather that level of transactional control be in my hands than dictated arbitrarily by a framework designer (even though Luke is super smart)
    That makes sense - but how can I acheive that?

    In my security config I have
    Code:
    <security:remember-me data-source-ref="dataSource"/>
    The dataSource bean looks like
    Code:
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    		<property name="driverClassName" value="${driverClassName}" />
    		<property name="url" value="jdbc:mysql://${hostname}/${schema}" />
    		<property name="username" value="${username}" />
    		<property name="password" value="${password}" />
    		<property name="defaultAutoCommit" value="false" />
    		<property name="defaultTransactionIsolation" value="2" /> <!-- READ_COMMITTED -->
    		<property name="validationQuery" value="SELECT 1 FROM DUAL;" />
    		<property name="maxActive" value="100" />
    		<property name="maxIdle" value="8" />
    		<property name="minIdle" value="2" />
    		<property name="maxWait" value="10000" />
    		<property name="removeAbandoned" value="true" />
    		<property name="removeAbandonedTimeout" value="10" />
    		<property name="testOnBorrow" value="true" />
    	</bean>
    This dataSource source is used through an LocalContainerEntityManagerFactoryBean and has the foloowing transactionManager bean defined.

    Code:
    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    		<property name="entityManagerFactory" ref="entityManagerFactory" />
    	</bean>
    But the security tag has bypassed all of this and is using JDBC and accessing the dataSource directly. So how do I always make this dataSource transactional however its used?

Posting Permissions

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