Announcement Announcement Module
Collapse
No announcement yet.
Custom implementation of Spring Security's UserDetailsService with Jpa/Hibernate Page Title Module
Move Remove Collapse
This topic is closed
X
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Custom implementation of Spring Security's UserDetailsService with Jpa/Hibernate

    Hello,

    I have problems using a custom implementation of UserDetailsService with a Spring 2.5/JPA/Hibernate configuration.

    If I implement UserDetailsService in my UserDao :
    HTML Code:
    <authentication-provider user-service-ref="userDao" />
    Then I've got an exception : org.hibernate.SessionException: Session is closed! when I try to get my User in the DAO :
    Code:
    	public UserDetails loadUserByUsername(String login) throws UsernameNotFoundException, DataAccessException {
    		User user = getUserByLogin(login);
    		
    		if (null == user) {
    			logger.error("User with login: " + login + " not found in database. Authentication failed for user " + login);
    			throw new UsernameNotFoundException("user not found in database");
    		}
    		
                    ......
    
    		acegiUser = new org.springframework.security.userdetails.User(user.getLogin(), user.getPassword(), true, true, true, true, new GrantedAuthority[] { new GrantedAuthorityImpl("ROLE_AUTH") });
    		
    		return acegiUser;
    	}
    If I implement UserDetailsService in my UserManager :
    HTML Code:
    <authentication-provider user-service-ref="userManager" />
    Then my manager becomes corrupted, I can't persist any User, each transaction is rollback ! And in the same way than previously, I have a Session is closed exception when getting the User.

    Can you help me and see what is the problem ?

    Thanks in advance for your help

    Here is the UserManager :
    Code:
    @Service("userManager")
    @Transactional(propagation = Propagation.REQUIRED, readOnly = true)
    public class UserManagerImpl implements UserManager {
    
    	private final Log logger = LogFactory.getLog(this.getClass());
    
    	@Autowired
    	private UserDao userDao;
    
    	public User getUserById(Integer id) {
    		return userDao.getUserById(id);
    	}
    
    	public User getUserByLogin(String login) {
    		return userDao.getUserByLogin(login);
    	}
    
    	public User getUserByFullname(String fullname) {
    		return userDao.getUserByFullname(fullname);
    	}
    	
    	public List<User> getAllUsers() {
    		return userDao.getAllUsers();
    	}
    
    	public List<User> searchUsers(String searchString) {
    		return userDao.searchUsers(searchString);
    	}
    
    	@Transactional(readOnly = false)
    	public User saveUser(User user) {
    		// New skill
    		if (null == user.getUserId()) {
    			return userDao.saveUser(user);
    		}
    		// Update skill
    		else {
    			return userDao.updateUser(user);
    		}
    	}
    
    	@Transactional(readOnly = false)
    	public void deleteUser(Integer id) {
    		userDao.deleteUser(getUserById(id));
    	}
    
    }
    And the JpaUserDao :
    Code:
    @Repository("userDao")
    public class JpaUserDao implements UserDao, UserDetailsService {
    
    	private final Log logger = LogFactory.getLog(this.getClass());
    
    	@PersistenceContext
    	private EntityManager em;
    
    	public User getUserById(Integer id) {
    		if (null == id) {
    			throw new IllegalArgumentException("Login is mandatory. Null value is forbidden.");
    		}
    		try {
    			Query query = em.createQuery("select u from User u where u.id = :id");
    			query.setParameter("id", id);
    			logger.info("get User with id: " + id);
    			User user = (User) query.getSingleResult();
    			return user;
    		} catch (PersistenceException e) {
    			// Critical errors : database unreachable, etc.
    			logger.error("Exception - PersistenceException occurs : " + e.getMessage() + " on complete getUserByLogin().");
    			return null;
    		}
    	}
    
    	public User getUserByLogin(String login) {
    		if (null == login) {
    			throw new IllegalArgumentException("Login is mandatory. Null value is forbidden.");
    		}
    		try {
    			Query query = em.createQuery("select u from User u where u.login like :login");
    			query.setParameter("login", login);
    			logger.info("get User with login: " + login);
    			User user = (User) query.getSingleResult();
    			return user;
    		} catch (PersistenceException e) {
    			// Critical errors : database unreachable, etc.
    			logger.error("Exception - PersistenceException occurs : " + e.getMessage() + " on complete getUserByLogin().");
    			return null;
    		}
    	}
    	
    	public List<User> getAllUsers() {
    		try {
    			Query query = em.createQuery("select u from User u");
    			logger.info("Get all users");
    			List<User> userList = (List<User>) query.getResultList();
    			return userList;
    		} catch (PersistenceException e) {
    			// Critical errors : database unreachable, etc.
    			logger.error("Exception - PersistenceException occurs : " + e.getMessage() + " on complete getUserByFullName().");
    			return null;
    		}
    	}
    
    	public void deleteUser(User user) {
    		try {
    			em.remove(user);
    			logger.info("Delete user: " + user.getFullname());
    		} catch (PersistenceException e) {
    			// Critical errors : database unreachable, etc.
    			logger.error("Exception - PersistenceException occurs : " + e.getMessage() + " on complete deleteSkill().");
    		}
    	}
    
    	public User saveUser(User user) {
    		try {
    			em.persist(user);
    			logger.info("Save user: " + user.getFullname());
    		} catch (PersistenceException e) {
    			// Critical errors : database unreachable, etc.
    			logger.error("Exception - PersistenceException occurs : " + e.getMessage() + " on complete saveUser().");
    		}
    
    		return user;
    	}
    	
    	public User updateUser(User user) {
    		try {
    			em.merge(user);
    			logger.info("Update user: " + user.getFullname());
    		} catch (PersistenceException e) {
    			// Critical errors : database unreachable, etc.
    			logger.error("Exception - PersistenceException occurs : " + e.getMessage() + " on complete saveUser().");
    		}
    
    		return user;
    	}
    
    	public UserDetails loadUserByUsername(String login) throws UsernameNotFoundException, DataAccessException {
    		User user = getUserByLogin(login);
    		
    		if (null == user) {
    			logger.error("User with login: " + login + " not found in database. Authentication failed for user " + login);
    			throw new UsernameNotFoundException("user not found in database");
    		}
    		
    		org.springframework.security.userdetails.User acegiUser;
    		
    		if(user.getLogin().equals("lfrering")) {
    			acegiUser = new org.springframework.security.userdetails.User(user.getLogin(), user.getPassword(), true, true, true, true, new GrantedAuthority[] { new GrantedAuthorityImpl("ROLE_SUPERVISOR") });
    		}
    		
    		acegiUser = new org.springframework.security.userdetails.User(user.getLogin(), user.getPassword(), true, true, true, true, new GrantedAuthority[] { new GrantedAuthorityImpl("ROLE_AUTH") });
    		
    		return acegiUser;
    	}
    
    }

  • #2
    My problem seems to be related with the foolowing issue which is marked as fixed and closed :
    http://forum.springframework.org/sho...detailsservice
    http://jira.springframework.org/brow...s:all-tabpanel

    But I use SpringSecurity 2.0.1 ant the problem happens. Any idea ?

    Comment


    • #3
      Hello,
      I've got news on my problem. I discovered than removing the annotations configuration in the application context resolve the problem :

      HTML Code:
      <!--global-method-security secured-annotations="enabled" /-->
      Then the UserManager which implements UserDetailsService works fine as well as the authentication with no session is closed exception.

      But as a consequence, I can't use the @Secured annotations.

      Any idea ?

      Comment


      • #4
        There was another persistence annotation issue raised recently

        http://jira.springframework.org/browse/SEC-826

        If that doesn't fix your problem, could you please post a test case which reproduces it.

        Comment


        • #5
          Hello luke and thank for this response.

          I'll give it a try as soon as possible and I'll keep you alert

          Comment


          • #6
            Hello Luke, hello all,
            With spring-security-*-2.0.2-20080518.150230-16.jar snapshot versions, the problem is resolved, I can now use security annotations with JPA

            Many thanks for your help !

            Comment

            Working...
            X