Results 1 to 5 of 5

Thread: Using a Hibernate UserDetails

  1. #1

    Default Using a Hibernate UserDetails

    This has been giving me problems for months now, and I'm thinking that there has to be a recommended way to do this. The problem is that, because my UserDetails is managed by Hibernate, it needs to NEVER be stored in anything more permanent then the request, since that's as long as the session lasts. However, if I try to get the principal out of the context and ACEGI hasn't had a reason to do any authentication yet, I get a stale one.

    I've tried locking the principal every time I get it, but then when it isn't stale, Hibernate whines at me for trying to lock an object twice. The best I can come up with is to wrap the principal in another getter:

    Code:
    principal = getUserById(principal.getUserId());
    but that just seems a little rediculous. Any ideas?

  2. #2
    Join Date
    Aug 2004
    Location
    Sydney, Australia
    Posts
    2,768

  3. #3

    Default

    Are you suggesting that I create a seperate UserDetails class for Acegi, then use that to fetch my User class? That seems overly complicated, and is essentially what I'm doing now anyway, except with another class. I guess I was just looking for a way to garantee that Acegi would grab a fresh User on every request, but that may not be possible.

  4. #4
    Join Date
    Aug 2004
    Location
    Sydney, Australia
    Posts
    2,768

    Default

    I'd suggest your AuthenticationDao retrieves your normal Party (or equivalent) object from the PartyDao (or equivalent). Then, create a subclass of User called MyUser. The MyUser object contains a holder for your Party instance (ie getParty()). Aside from that, MyUser is simply the standard User. This allows anywhere in your code for you to access the Party, via ((SecureContext) ContextHolder.getContext()).getAuthentication().ge tPrincipal().getParty().

    If getting a fresh User each invocation is your concern, you just need to remove the caching collaborator defined against DaoAuthenticationProvider, which will cause it to use NullUserCache by default.

    Alternatively, the root cause of your requirement is probably ensuring updates to the Party are immediately reflected in the security layer. The recommended way of doing that is to use the evict method defined against the UserCache wired against your DaoAuthenticationProvider. This evict method is called by services layer Party mutator methods. In effect this gives you the benefits of UserCache caching without the trade-off of stale data.

  5. #5

    Default

    Code:
    /*
     * Created on 2005-2-20
     *
     * TODO To change the template for this generated file go to
     * Window - Preferences - Java - Code Style - Code Templates
     */
    
    
    import java.util.Iterator;
    
    import net.sf.acegisecurity.GrantedAuthority;
    import net.sf.acegisecurity.GrantedAuthorityImpl;
    import net.sf.acegisecurity.UserDetails;
    import net.sf.acegisecurity.providers.dao.AuthenticationDao;
    import net.sf.acegisecurity.providers.dao.UsernameNotFoundException;
    import net.sf.hibernate.HibernateException;
    import net.sf.hibernate.Query;
    import net.sf.hibernate.Session;
    import net.sf.hibernate.SessionFactory;
    
    import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;
    import org.springframework.dao.DataAccessException;
    import org.springframework.dao.DataRetrievalFailureException;
    import org.springframework.orm.hibernate.SessionFactoryUtils;
    
    
    /**
     * @author Creatxr
     *
     */
    public class AuthenticationDaoHibernateImpl implements AuthenticationDao {
    	/**
    	 * Logger for this class
    	 */
    	private static final Log logger = LogFactory
    			.getLog(AuthenticationDaoHibernateImpl.class);
    
    	private SessionFactory sessionFactory;
    
    	/*
    	 * (non-Javadoc)
    	 *
    	 * @see net.sf.acegisecurity.providers.dao.AuthenticationDao#loadUserByUsername(java.lang.String)
    	 */
    	public UserDetails loadUserByUsername(String username)
    			throws UsernameNotFoundException, DataAccessException {
    		Session session = null;
    
    		try {
    			session = SessionFactoryUtils.getSession(sessionFactory, true);
    			Query query = session.createQuery("from UserDetails userDetails where userDetails.username=:username");
    			query.setString("username", username);
    			Iterator it = query.iterate();
    			if (it.hasNext()) {
    				com.fjky.xfile.core.orm.UserDetails row = (com.fjky.xfile.core.orm.UserDetails)it.next();
    
    				UserDetailsImpl userDetails = new UserDetailsImpl();
    				userDetails.setUsername(username);
    				userDetails.setPassword(row.getPassword());
    				userDetails.setEnabled(row.getEnabled().booleanValue());
    				userDetails.setAccountNonExpired(row.getAccountNonExpired().booleanValue());
    				userDetails.setCredentialsNonExpired(row.getCredentialsNonExpired().booleanValue());
    				userDetails.setAccountNonLocked(row.getAccountNonLocked().booleanValue());
    				String[] authoriesArray = row.getAuthorities().split(",", 0);
    				GrantedAuthority[] grantedAuthority = new GrantedAuthority[authoriesArray.length];
    				for &#40;int i=0; i<authoriesArray.length; i++&#41; &#123;
    					grantedAuthority&#91;i&#93; = new GrantedAuthorityImpl&#40;authoriesArray&#91;i&#93;.trim&#40;&#41;&#41;;
    				&#125;
    
    				userDetails.setAuthorities&#40;grantedAuthority&#41;;
    
    				return userDetails;
    			&#125; else &#123;
    				throw new UsernameNotFoundException&#40;username&#41;;
    			&#125;
    		&#125; catch&#40;HibernateException he&#41; &#123;
    			throw SessionFactoryUtils.convertHibernateAccessException&#40;he&#41;;
    		&#125; catch&#40;UsernameNotFoundException e&#41; &#123;
    			logger.error&#40;"loadUserByUsername&#40;String&#41;", e&#41;;
    			throw new DataRetrievalFailureException&#40;"loadUserByUsername&#40;String&#41;", e&#41;;
    		&#125; finally &#123;
    			SessionFactoryUtils.closeSessionIfNecessary&#40;session, sessionFactory&#41;;
    		&#125;
    	&#125;
    
    	public SessionFactory getSessionFactory&#40;&#41; &#123;
    		return sessionFactory;
    	&#125;
    
    	public void setSessionFactory&#40;SessionFactory sessionFactory&#41; &#123;
    		this.sessionFactory = sessionFactory;
    	&#125;
    &#125;

Similar Threads

  1. Replies: 5
    Last Post: Dec 27th, 2005, 07:00 AM
  2. Loosing my SecureContext
    By sklakken in forum Security
    Replies: 3
    Last Post: Jul 21st, 2005, 01:44 PM
  3. Replies: 3
    Last Post: Nov 19th, 2004, 07:16 PM
  4. Replies: 9
    Last Post: Sep 25th, 2004, 12:35 PM
  5. Replies: 7
    Last Post: Aug 21st, 2004, 03:42 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •