[英]Should a Shiro Authenticating Realm be transactional?
I'm using Shiro to secure my Spring MVC webapp. 我正在使用Shiro来保护我的Spring MVC webapp。 I'm using Hibernate for persistence and so I have a HibernateRealm to get and populate an AuthenticationInfo object.
我正在使用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
is my custom user class. Account
是我的自定义用户类。 I use the DAO to retrieve an Account
by username. 我使用DAO通过用户名检索
Account
。 I was wondering if there is any point in making this method @Transactional
. 我想知道这个方法
@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 我也有以下问题:DAO执行
sessionFactory.getCurrentSession()
来获取会话,但我得到了一个
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. 我无法理解为什么Spring没有为我开会。
Edit: To login, we do this in a Spring @Controller
method using Shiro's Subject
编辑:要登录,我们使用Shiro的
Subject
在Spring @Controller
方法中执行此操作
@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. 在内部,Shiro使用我上面的领域方法来获取存储的用户名/密码信息。 It uses an
@Autowired
DAO to check my database for the right account. 它使用
@Autowired
DAO检查我的数据库是否有正确的帐户。 It then matches the passwords with a CredentialsMatcher
implementation. 然后,它将密码与
CredentialsMatcher
实现进行匹配。
So you have two problems. 所以你有两个问题。 It is usually better to split such questions into two, since these problems are not really connected to each other.
通常最好将这些问题分成两部分,因为这些问题并没有真正相互联系。
@Transactional
annotations does not work. @Transactional
注释不起作用。 To be sure you may run you code or tests in Debug mode and look for the JdkDynamicAopProxy or something similar in the stack - if it is present, than your Realm is invoked through transactions-intercepting proxy, but I suppose that there is no proxy curently. @Transactional(readOnly=true)
may improve your performance with proper configuration (eg for the really high-loaded application readOnly queries may use secondary replica of the DB Server). @Transactional(readOnly=true)
可以通过正确配置提高性能(例如,对于真正高负载的应用程序,readOnly查询可能使用数据库服务器的辅助副本)。 It is really easier to setup the java.sql.Connection.setReadOnly()
method as part of the Spring transactions, than in the other way. java.sql.Connection.setReadOnly()
方法设置为Spring事务的一部分比在其他方面更容易。 It appears that Spring isn't creating a transactional proxy for your Realm bean. 看来Spring并没有为你的Realm bean创建一个事务代理。 This is the only reason that I can see why a Hibernate Session isn't available - because the backing infrastructure isn't there (on the thread) ready for use.
这是我可以理解为什么Hibernate会话不可用的唯一原因 - 因为支持基础设施不存在(在线程上)可供使用。
As to your question, if you do want to mark it @Transactional
, you might consider specifying @Transactional(readOnly=true)
至于你的问题,如果你想将它标记为
@Transactional
,你可以考虑指定@Transactional(readOnly=true)
Shiro creates it's own instance of my Realm and therefore Spring has no power over it to wrap it in a proxy. Shiro创建了它自己的Realm实例,因此Spring没有权力将它包装在代理中。 That's why it can't add the transactional behavior.
这就是为什么它无法添加事务行为。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.