Announcement Announcement Module
Collapse
No announcement yet.
Using a Hibernate UserDetails Page Title Module
Move Remove Collapse
This topic is closed
X
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • 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
    Here are some previous answers that might help:

    http://forum.springframework.org/viewtopic.php?t=4181
    http://forum.springframework.org/viewtopic.php?t=4150
    http://forum.springframework.org/viewtopic.php?t=3298
    http://forum.springframework.org/viewtopic.php?t=3283

    Comment


    • #3
      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.

      Comment


      • #4
        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.

        Comment


        • #5
          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;

          Comment

          Working...
          X