我正在将 grails 2.4.5 应用程序迁移到 grails 3.1.11。应用程序有一个自定义的 authprovider,它允许用户从 db 或 ldap 服务器进行身份验证。如果用户是 ldap 用户,则从 ldap 验证登录凭据,如果不是从 db 验证。角色是从数据库加载的。此方案在 grails 2.4.5 中运行良好
当迁移到 grails 3.1.11 时,当我想访问数据库时,在 CustomLdapAuthenticationProvider 中抛出“org.hibernate.HibernateException:没有为当前线程找到会话”。如果我将@Transactional 放在该方法上,错误就会消失。我不知道这是正确的方法,因为我认为 grails 会在 Web 请求中处理会话。
我的代码是这样的
....
class CustomLdapAuthenticationProvider extends LdapAuthenticationProvider {
def ldapAuthProvider
def daoAuthenticationProvider
def springSecurityService
def userDetailsService
def dataSource
def grailsApplication
CustomLdapAuthenticationProvider(LdapAuthenticationProvider ldapAuthenticationProvider) {
super(ldapAuthenticationProvider.authenticator, ldapAuthenticationProvider.authoritiesPopulator)
}
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
String username = authentication.principal?.toString()?.toLowerCase()
String password = authentication.credentials
Boolean isExistingLdapUser = User.withCriteria {
eq("personUsername", username)
eq("personIsldap", true)
}[0] as Boolean
if (isExistingLdapUser) {
authentication = ldapAuthProvider.authenticate(authentication)
springSecurityService.loggedIn ? Person.findByPersonUsername(authentication.principal.username) : null
.....
.....
.....
}
}
有什么建议么?我必须手动管理会话吗?
编辑:
添加@Transactional 注释来验证grails 3 版本的方法解决了我的问题。
@Override
@Transactional
public Authentication authenticate(Authentication authentication) throws AuthenticationException {