Background
I'm using the Spring Security Grails plugin. Because my User and Role classes are not GORM objects, I I've replaced the UserDetailsService
provided by the plugin with my own implementation:
class CustomUserDetailsService implements UserDetailsService {
static transactional = false
private static final log = LogFactory.getLog(this)
@Autowired
private UserManager userManager
@Autowired
private RoleManager roleManager
UserDetails loadUserByUsername(String username) {
User user = userManager.getUserByEmail(username)
UserDetails userDetails = new UserAdapter(user, roleManager)
log.debug "user '$username' has roles: ${userDetails.authorities?.authority}"
userDetails
}
}
Problem
When I login, I see the following message is logged from CustomUserDetailsService.loadUserByUsername()
user '[email protected]' has roles: [USER]
So it seems that the user has been assigned the USER role. However, when I then try and access an action of this controller:
@Secured(['ROLE_USER', 'ROLE_ADMINISTRATOR'])
class MyProfileController {
def someAction = { // impl omitted }
}
I get bounced to the access denied page. I'm pretty sure that the user is logged in, because the access denied page contains markup such as
<sec:ifLoggedIn>
protected content
</sec:ifLoggedIn>
and the protected content is displayed. So it seems that somehow the USER role is not associated with the current user, when the controller authorisation is performed. The log message suggests that the UserDetailsService
is OK.
getCurrentUser()
is a utility method for users, but it's not used by the plugin or Spring Security, so it's not related to this issue. Try setting the 'org.springframework.security' category to debug in your Log4j config - Spring Security is good about dumping verbose info about auth failures. – Burt BeckwithRoleVoter
ignores them. – Burt BeckwithGrantedAuthority.authority
should return a String that begins with 'ROLE_'? – Dónal