Announcement Announcement Module
Collapse
No announcement yet.
Hibernate problem with Spring security UserDetailsService Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Hibernate problem with Spring security UserDetailsService

    Hello,
    I'm trying to use Spring Security with a custom Hibernate UserDetailsService.

    Every time the user attempts to log in I get a "No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here" exception.

    I also use BlazeDS Integration but I don't think the problem is related to the Flex/BlazeDS part of the application.

    Here are my configuration files

    web.xml

    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
    <web-app>
    
    	<display-name>flextest</display-name>
    	<description>Flex Test</description>
    
    
    	<servlet>
    		<servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
    		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    		
    		<init-param>
    			<param-name>contextConfigLocation</param-name>
    			<param-value>/WEB-INF/application-config.xml
    				         /WEB-INF/applicationContext-security.xml
    			</param-value>
    		</init-param>		
    		<load-on-startup>1</load-on-startup>		
    	</servlet>
    	
    	<servlet-mapping>
    		<servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
    		<url-pattern>/application/*</url-pattern>
    	</servlet-mapping>
    	
    	<welcome-file-list>
    		<welcome-file>main.html</welcome-file>
    		<welcome-file>index.html</welcome-file>
    		<welcome-file>index.htm</welcome-file>
    	</welcome-file-list>
    
    </web-app>

    application-config.xml

    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:sec="http://www.springframework.org/schema/security" xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:flex="http://www.springframework.org/schema/flex" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd http://www.springframework.org/schema/flex http://www.springframework.org/schema/flex/spring-flex-1.0.xsd ">
    	
    	<context:property-placeholder location="/WEB-INF/jdbc.properties" />
    	
    
    	<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource" p:driverClassName="${jdbc.driverClassName}" 
    	p:url="${jdbc.url}" p:username="${jdbc.username}" p:password="${jdbc.password}"/>
    
    
    
    	<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"
    	p:dataSource-ref="dataSource" p:mappingDirectoryLocations="classpath:com/flextest/domain/hibernate/hbm/">
    
    		<property name="hibernateProperties">
    			<props>
    				<prop key="hibernate.dialect">${hibernate.dialect}</prop>
    				<prop key="hibernate.show_sql">true</prop>
    			</props>
    		</property>
    
    	</bean>
    	
    	<tx:annotation-driven transaction-manager="txManager"/>
    	
    	<bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager" p:sessionFactory-ref="sessionFactory"/>
    
    
    	<bean id="userRepository" class="com.flextest.domain.UserHome">
    		<property name="sessionFactory" ref="sessionFactory" />
    		
    	</bean>
    
    
    	<flex:message-broker>
    		<flex:secured per-client-authentication="true"/>
    
    	</flex:message-broker>
    
    
    	<bean id="userRegistrationService" class="com.flextest.business.UserRegistrationServiceImpl">
    		<property name="userRepository" ref="userRepository" />
    		
    		<flex:remoting-destination />
    		<sec:intercept-methods>
    			<sec:protect method="testMethod" access="ROLE_USER" />
    		</sec:intercept-methods>
    	</bean>
    
    </beans>

    applicationContext-security.xml

    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:sec="http://www.springframework.org/schema/security"
    	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
    		http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.2.xsd">
    
    	<sec:http auto-config="true" session-fixation-protection="none"/>
    	
    
    	<sec:authentication-provider user-service-ref="userRepository"/>
    
    </beans>

    The UserHome class implements UserDetailsService and related method

    Code:
    import org.hibernate.SessionFactory;
    import org.springframework.security.userdetails.UserDetails;
    import org.springframework.security.userdetails.UserDetailsService;
    
    
    public class UserHome implements  UserDao, UserDetailsService{
    	
    	private SessionFactory sessionFactory;
    
    	
    	public void setSessionFactory(SessionFactory sessionFactory) {
    		this.sessionFactory = sessionFactory;
    	}
    	
    	
    	public UserDetails loadUserByUsername(String username)
    			throws UsernameNotFoundException, DataAccessException {
    		return findById(username);
    	}
    
    
    
    public User findById(java.lang.String id) {
    
    		try {
    			
    			User instance = (User) sessionFactory.getCurrentSession().get("com.flextest.domain.User", id);
    		
    			if (instance == null) {
    				...
    			} else {
    				...
    				
    			}
    			return instance;
    		} catch (RuntimeException re) {
    			log.error("get failed", re);
    			throw re;
    		}
    	}
    ...
    }
    Can anyone help me solve the problem?

    Thanks in advance

  • #2
    As an additional detail, if I don't use Spring security the exception remains but if I use transaction annotation on the service method (even @Transactional(propagation=Propagation.NEVER)) everything works fine.

    Adding such annotation while using Spring security doesn't solve the problem. Ithink there is a configuration broblem

    Comment


    • #3
      Open Session in View

      By default there is no hibernate session bound to an HTTP request unless you make it happen.

      Luckily there's a handy interceptor provided by Spring that you can configure in your web.xml file, it will bind a new hibernate session to every HTTP request made to the path the filter is specified for. This is an easy way of achieving the 'Open Session in View' hibernate session pattern.

      For example:
      Code:
      <filter>
        <filter-name>HibernateSession</filter-name>
        <filter-class>
          org.springframework.orm.hibernate3.support.OpenSessionInViewFilter
        </filter-class>
      </filter>
      
      <filter-mapping>
        <filter-name>HibernateSession</filter-name>
        <url-pattern>/*</url-pattern>
      </filter-mapping>

      Comment


      • #4
        I recently ran into the exact same sort of error, and beat my head against the wall trying to figure out what the problem was.

        In my case, I was using the `OpenSessionInViewFilter` configured in the `web.xml` file, along with the Spring Security configuration there as well.

        Since both Spring Security and `OpenSessionInViewFilter` are filters, the order in which they are applied depends on the order they appear in the `web.xml` file.

        In my case, I initially had the `OpenSessionInViewFilter` below the Spring Security filter. Once I swapped their positions (ie. put the `OpenSessionInViewFilter` above the Spring Security one), everything worked just fine!

        Comment

        Working...
        X