J'essaie d'intégrer Spring Security avec Hibernate. Je suis novice en ce qui concerne les deux technologies, donc je vais certainement prendre trop de mesures à la fois ici, mais je suis au point où je veux authentifier un utilisateur de la base de données. Je pense que c'est plus un problème de Hibernate qu'un Spring Security, mais je le mentionne pour donner un peu de contexte. Voici le message d'erreur et le code. Quelqu'un peut-il repérer quelque chose?org.hibernate.HibernateException: Aucune session actuellement liée au contexte d'exécution
org.hibernate.HibernateException: No session currently bound to execution context
org.hibernate.context.ManagedSessionContext.currentSession(ManagedSessionContext.java:74)
org.hibernate.impl.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:622)
com.vicinity.dao.hibernate.GenericHibernateDAO.findByCriteria(GenericHibernateDAO.java:99)
com.vicinity.dao.hibernate.HibernateUserDAO.getUserByLogin(HibernateUserDAO.java:35)
com.vicinity.service.PersistentUserManager.loadUserByUsername(PersistentUserManager.java:67)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
java.lang.reflect.Method.invoke(Unknown Source)
org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:307)
org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:107)
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
$Proxy31.loadUserByUsername(Unknown Source)
org.springframework.security.authentication.dao.DaoAuthenticationProvider.retrieveUser(DaoAuthenticationProvider.java:83)
org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider.authenticate(AbstractUserDetailsAuthenticationProvider.java:125)
org.springframework.security.authentication.ProviderManager.doAuthentication(ProviderManager.java:121)
org.springframework.security.authentication.AbstractAuthenticationManager.authenticate(AbstractAuthenticationManager.java:49)
org.springframework.security.authentication.ProviderManager.doAuthentication(ProviderManager.java:139)
org.springframework.security.authentication.AbstractAuthenticationManager.authenticate(AbstractAuthenticationManager.java:49)
org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter.attemptAuthentication(UsernamePasswordAuthenticationFilter.java:98)
org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:200)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:356)
org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:106)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:356)
org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:80)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:356)
org.springframework.security.web.session.ConcurrentSessionFilter.doFilter(ConcurrentSessionFilter.java:108)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:356)
org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:150)
org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:237)
org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:167)
Configuration de la gestion de DAO et de transaction:
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="configLocation">
<value>classpath:hibernate.cfg.xml</value>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean id="hibernateUserDAO" class="com.vicinity.dao.hibernate.HibernateUserDAO">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean id="userManagerTarget" class="com.vicinity.service.PersistentUserManager">
<property name="userDAO" ref="hibernateUserDAO" />
</bean>
<bean id="userManager" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager">
<ref local="transactionManager" />
</property>
<property name="target">
<ref local="userManagerTarget" />
</property>
<property name="transactionAttributes">
<props>
<prop key="loadUserByUsername">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
Voici la classe qui implémente l'UserDetailsService
qui est appelé à authentifier l'utilisateur. Cela fait un appel à la DAO, voir la ligne userDAO.getUserByLogin(login);
:
@Service("userManager")
@Transactional(propagation = Propagation.REQUIRED, readOnly = true)
public class PersistentUserManager implements UserManager, UserDetailsService {
@Override
public UserDetails loadUserByUsername(String login) throws UsernameNotFoundException, DataAccessException {
User user = userDAO.getUserByLogin(login);
if (null == user) {
logger.error("User with login: " + login + " not found in database");
throw new UsernameNotFoundException("user not found in database");
}
org.springframework.security.core.userdetails.User springUser;
springUser = new org.springframework.security.core.userdetails.User(user.getLogin(), user.getPassword(), true,
true, true, true, new ArrayList<GrantedAuthority>());
return springUser;
}
}
Voici le DAO qui se lit de la base de données. Notez que je suis en train de profiter du « modèle GenericDAO »:
@Repository("userDAO")
public class HibernateUserDAO extends GenericHibernateDAO<User, Long> implements UserDAO {
public HibernateUserDAO() {
super(User.class);
}
@Override
public void createUser(User user) {
super.makePersistent(user);
}
public User getUserByLogin(String login) {
if (null == login) {
throw new IllegalArgumentException("You must provide a username if you want to get the user.");
}
List<User> users = findByCriteria(Restrictions.eq("login", login));
// TODO, might need to check here if there are more than one user with the same username
if(users == null || users.size() == 0) {
return null;
} else {
return users.get(0);
}
}
}
est ici la classe où l'erreur se produit, la ligne Criteria crit = getSessionFactory().getCurrentSession().createCriteria(getPersistentClass());
:
public abstract class GenericHibernateDAO<T, ID extends Serializable> implements GenericDAO<T, ID> {
private Class<T> persistentClass;
private SessionFactory sessionFactory;
@SuppressWarnings("unchecked")
protected List<T> findByCriteria(Criterion... criterion) {
Criteria crit = getSessionFactory().getCurrentSession().createCriteria(getPersistentClass());
for (Criterion c : criterion) {
crit.add(c);
}
return crit.list();
}
}
je suit dans ma configuration de mise en veille prolongée (hibernate.cfg.xml) qui peut être relavent:
<property name="current_session_context_class">org.hibernate.context.ManagedSessionContext</property>
Non. Mais j'ai maintenant édité mon article original. Même erreur mais je peux voir l'AOP au moins. Pouvez-vous jeter un coup d'oeil? – chrisjleu