Grails springSecurityService.currentUser returns 空

Grails springSecurityService.currentUser returns null

我有这项服务class:

class UserService {

    def springSecurityService

    @Listener(topic = 'currentUser', namespace = 'auth')
    public User getCurrentUser(){
        return springSecurityService.currentUser
    }

    def authenticate(OAuthToken oAuthToken){
        SecurityContextHolder.context.authentication = oAuthToken
        return springSecurityService.currentUser
    }
}

如果我使用身份验证方法,springSecurityService.currentUser returns 当前用户。但是,如果我已经登录,我想使用 getCurrentUser 方法获取当前用户,并且它 returns 为空。我调试了Springsecurityservice.getCurrentUser方法和"isLoggedIn"方法returns false.

但如果我在我看来尝试这样做,它会起作用:

<sec:ifLoggedIn>Yeeees</sec:ifLoggedIn>

更新:

当我运行 UserService.getCurrentUser SecurityService SCH.context.authentication returns 为空。在该调用之后,将呈现视图并且 SCH.context.authentication returns 正确的身份验证。

更新 2:

我分析了它,它似乎只有在我将它与事件总线一起使用时才会发生。如果我直接从控制器调用 getCurrentUser,它工作正常,但如果我使用事件总线,它就不行。 我使用来自平台核心插件的事件总线。事件总线还有另一个 SCH.context 吗?

我找到了解决办法。问题是事件总线在一个线程中工作,spring 上下文默认不会传递给线程。

配置中的选项'context holder strategy'解决了这个问题:

grails.plugin.springsecurity.sch.strategyName = org.springframework.security.core.context.SecurityContextHolder.MODE_INHERITABLETHREADLOCAL

http://grails-plugins.github.io/grails-spring-security-core/latest/#miscProperties

你可以获取主体然后搜索用户,在我的例子中域是AppUser

        def user = springSecurityService.getPrincipal()
        def testUser =AppUser.findByUsername(user.username)