Announcement Announcement Module
Collapse
No announcement yet.
Spring security + Hibernate!! ERROR!! Please HELP!! Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Spring security + Hibernate!! ERROR!! Please HELP!!

    I'm trying to implement a login mechanism using Spring Security and Hibernate.

    The settings work fine when I hardcode the login values in my DAO itself and run the application. But when I try to use Hibernate it throws the following error:

    Code:
    No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here
    My spring-security.xml file
    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
        xmlns:security="http://www.springframework.org/schema/security"
    	xsi:schemaLocation="http://www.springframework.org/schema/beans 
    	   		http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    			http://www.springframework.org/schema/security 
    			http://www.springframework.org/schema/security/spring-security-3.0.xsd">
    	
    	<!-- This is where we configure Spring-Security  -->
    	<security:http auto-config="true" use-expressions="true" access-denied-page="/auth/denied" >
    	
    		<security:intercept-url pattern="/auth/login" access="permitAll"/>
    		<security:intercept-url pattern="/main/admin" access="hasRole('ROLE_ADMIN')"/>
    		<security:intercept-url pattern="/main/common" access="hasRole('ROLE_USER')"/>
    		
    		<security:form-login
    				login-page="/auth/login" 
    				authentication-failure-url="/auth/login?error=true" 
    				default-target-url="/main/common"/>
    			
    		<security:logout 
    				invalidate-session="true" 
    				logout-success-url="/auth/login" 
    				logout-url="/auth/logout"/>
    	
    	</security:http>
    	
    	<!-- Declare an authentication-manager to use a custom userDetailsService -->
    	<security:authentication-manager>
    	        <security:authentication-provider user-service-ref="loginService">
    	        		<security:password-encoder ref="passwordEncoder"/>
    	        </security:authentication-provider>
    	</security:authentication-manager>
    	
    	<!-- Use a Md5 encoder since the user's passwords are stored as Md5 in the database -->
    	<bean class="org.springframework.security.authentication.encoding.Md5PasswordEncoder" id="passwordEncoder"/>
    
    	<!-- A custom service where Spring will retrieve users and their corresponding access levels  -->
    	<bean id="loginService" class="com.myaudition.contact.service.LoginService"/>
    	
    </beans>
    In my spring-servlet.xml I've the transaction manager defined(which works fine for the rest of the application)
    Code:
    <bean id="transactionManager"
            class="org.springframework.orm.hibernate3.HibernateTransactionManager">
            <property name="sessionFactory" ref="sessionFactory" />
        </bean>
    The login service class:
    Code:
    @Service
    public class LoginService implements UserDetailsService {
    	
    	@Autowired
    	private UserDAO userDAO;
    
    	@Transactional
    	public UserDetails loadUserByUsername(String username)
    			throws UsernameNotFoundException, DataAccessException {
    
    		UserDetails user = null;
    		
    		try {
    			Login dbUser = userDAO.searchDatabase(username);
    			
    			user =  new User(
    					dbUser.getEmail(), 
    					dbUser.getPassword().toLowerCase(),
    					true,
    					true,
    					true,
    					true,
    					getAuthorities(dbUser.getIdentifierId()) );
    
    		} catch (Exception e) {
    			throw new UsernameNotFoundException("Error in retrieving user");
    		}
    		
    		return user;
    	}
    The UserDAO class:
    Code:
    @Repository
    public class UserDAO {
    
    	@Autowired
        private SessionFactory sessionFactory;
    	
    	/**
    	 * Simulates retrieval of data from a database.
    	 */
    	@SuppressWarnings("unchecked")
    	public Login searchDatabase(String username) {
    		// Retrieve all users from the database
    		List<Login> users = new ArrayList<Login>();
    
    		Session session = sessionFactory.getCurrentSession();
    
    		Query query = session.createQuery(" from Login");
    		users = query.list();
    
    		// Search user based on the parameters
    		for(Login dbUser:users) {
    			if ( dbUser.getEmail().equals(username)  == true ) {
    				// return matching user
    				return dbUser;
    			}
    		}
    		throw new RuntimeException("User does not exist!");
    	}
    }
    In the above code, the code breaks while trying to get the current session & gives the following error:

    Code:
    No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here
    Please guide me. How do i attach a hibernate session with this thread? What am i doing wrong?

  • #2
    use spring open session in view filter and make sure it fires before "filterChainProxy" .



    http://static.springsource.org/sprin...iewFilter.html

    Comment


    • #3
      You are using @Transactional but have not configured anything that knows what to with @Transactional. Use the tx namespace to add tx:annotation-driven..

      Also the security stuff is loaded by the contextloaderlistener which doesn't know anything about beans defined in the servlet context (child (servlet) can see the parent (ContextLoaderLIstener) but not the other way around).

      Comment


      • #4
        Originally posted by cablepuff View Post
        use spring open session in view filter and make sure it fires before "filterChainProxy" .



        http://static.springsource.org/sprin...iewFilter.html
        I'm already using open Session In View Interceptor in my spring-servlet.xml

        like this:
        Code:
            <mvc:interceptors>
        	    <bean id="openSessionInViewInterceptor"
        	    	class="org.springframework.orm.hibernate3.support.OpenSessionInViewInterceptor">
        	        <property name="sessionFactory">
        	            <ref local="sessionFactory" />
        	        </property>
        	    </bean>
        	</mvc:interceptors>
        And my spring security filter chain is defined in web.xml
        Code:
        <filter>
        	        <filter-name>springSecurityFilterChain</filter-name>
        	        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
        	</filter>
        Am i doing it wrong?

        Comment


        • #5
          Originally posted by Marten Deinum View Post
          You are using @Transactional but have not configured anything that knows what to with @Transactional. Use the tx namespace to add tx:annotation-driven..

          Also the security stuff is loaded by the contextloaderlistener which doesn't know anything about beans defined in the servlet context (child (servlet) can see the parent (ContextLoaderLIstener) but not the other way around).
          I'm already using the following in my spring-servlet.xml
          Code:
          <mvc:annotation-driven />
          Other parts of my application is working fine. Other services where functions are marked @Transactional is working fine. Please guide.

          Comment


          • #6
            Originally posted by Marten Deinum View Post
            You are using @Transactional but have not configured anything that knows what to with @Transactional. Use the tx namespace to add tx:annotation-driven..

            Also the security stuff is loaded by the contextloaderlistener which doesn't know anything about beans defined in the servlet context (child (servlet) can see the parent (ContextLoaderLIstener) but not the other way around).
            Hey guys, I found the solution to it. Marten you're right, it was caused as the spring security descriptor was loaded by contextloaderlistener which doesn't know anything of my beans. So i made 3 diff xmls, applicationContext.xml,
            hibernate-context.xml and spring-security.xml. Apart from that I still have my spring-servlet.xml with minimal config.

            Solved the problem by defining tx:annotation-driven in hibernate properties and mvc:annotation-driven in applicationContext.xml

            Thanks guys.

            Comment

            Working...
            X