I’m using Shiro to secure my Spring MVC webapp. I’m using Hibernate for persistence and so I have a HibernateRealm to get and populate an AuthenticationInfo object.
@Override
@Transactional
protected AuthenticationInfo doGetAuthenticationInfo(
AuthenticationToken token) throws AuthenticationException {
Account account = accountDao.findByUsername((String)token.getPrincipal());
SimplePrincipalCollection principals = new SimplePrincipalCollection(account, getName());
SimpleAccount info = new SimpleAccount(principals, account.getPassword());
return info;
}
Account is my custom user class. I use the DAO to retrieve an Account by username. I was wondering if there is any point in making this method @Transactional. This is a read only operation after all.
I’m also having the following problem: the DAO does sessionFactory.getCurrentSession() to get a session, but I’m getting a
HibernateException: No Session found for current thread
when the method gets called. I have these in my application context:
<tx:annotation-driven transaction-manager = "transactionManager" />
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
I can’t understand why Spring isn’t opening a session for me.
Edit: To login, we do this in a Spring @Controller method using Shiro’s Subject
@RequestMapping(value = "/account/login", method = RequestMethod.POST)
public String login(@RequestParam("username") String username, @RequestParam("password") String password) {
Subject currentUser = SecurityUtils.getSubject();
if (!currentUser.isAuthenticated) {
UsernamePasswordToken token = new UsernamePasswordToken(username, password);
currentUser.login(token);
return "profile";
}
return "home";
}
Internally, Shiro uses the realm method I have above to get the stored username/password information. It uses an @Autowired DAO to check my database for the right account. It then matches the passwords with a CredentialsMatcher implementation.
Shiro creates it’s own instance of my Realm and therefore Spring has no power over it to wrap it in a proxy. That’s why it can’t add the transactional behavior.