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?