I'm unable to get springSecurityService.currentUser from a controller in Grails 3.2.8.
Please note that Grails 3.2.8 made some performance improvements not in previous versions that seem to be breaking Spring Security Core. As per Grails 3.2.8 dependency injection in domain classes, I set grails.gorm.autowire = true, which fixed that incompatibility.
Steps to reproduce:
Create a new Grails 3.2.8 web app with Spring Security 3.1.1 using Roles and Groups.
In application.yml, set grails.gorm.autowire = true
In Bootstrap:
def init = { servletContext ->
User user = new User(username: 'foo', password:'foo').save(flush: true)
Role role = new Role(authority: 'SomeRole').save(flush: true)
RoleGroup roleGroup = new RoleGroup(name: 'SomeRole').save(flush: true)
RoleGroupRole.create(roleGroup, role)
UserRoleGroup.create(user, roleGroup)
}
Create a controller TestController:
@Secured(['SomeRole'])
class TestController {
def springSecurityService
def index() {
println "springSecurityService==null? ${(springSecurityService==null).toString()}"
println "SecurityContextHolder.context==null? ${(SecurityContextHolder.context==null).toString()}"
println "SecurityContextHolder.context?.authentication==null? ${(SecurityContextHolder.context?.authentication==null).toString()}"
println "springSecurityService.principal==null? ${(springSecurityService.principal==null).toString()}"
println "springSecurityService.currentUser==null? ${(springSecurityService.currentUser==null).toString()}"
render "1" //Render something so we don't get an exception.
}
}
Start up the server and go to /test. The output is:
springSecurityService==null? false
SecurityContextHolder.context==null? false
SecurityContextHolder.context?.authentication==null? true
springSecurityService.principal==null? true
springSecurityService.currentUser==null? true`
Is there a good workaround?
If SecurityContextHolder.context
is not null (it should never be null) but
SecurityContextHolder.context?.authentication
is null, then this is probably not a Grails or a plugin issue - you're not authenticated. So there's no principal to get the cached user id from (i.e. springSecurityService.principal
is null as your output shows) and there's no way to retrieve the current User instance.