我正在使用 Shiro 来保护我的 Spring MVC webapp。我使用 Hibernate 进行持久性,所以我有一个 HibernateRealm 来获取和填充一个 AuthenticationInfo 对象。
@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
是我的自定义用户类。我使用 DAOAccount
按用户名检索。我想知道制作这种方法是否有任何意义@Transactional
。毕竟这是一个只读操作。
我也遇到了以下问题:DAO 确实sessionFactory.getCurrentSession()
会获得一个会话,但我得到了一个
HibernateException: No Session found for current thread
当方法被调用时。我在我的应用程序上下文中有这些:
<tx:annotation-driven transaction-manager = "transactionManager" />
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
我不明白为什么 Spring 不为我打开会话。
编辑:要登录,我们@Controller
使用 Shiro 的 Spring 方法执行此操作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";
}
在内部,Shiro 使用我上面的领域方法来获取存储的用户名/密码信息。它使用@Autowired
DAO 检查我的数据库中是否有正确的帐户。然后它将密码与CredentialsMatcher
实现进行匹配。