使用 Spring Security Grails 插件进行授权
背景
我正在使用 Spring Security Grails 插件。因为我的 User 和 Role 类不是 GORM 对象,所以我用自己的实现替换了插件提供的 UserDetailsService
:
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
}
}
问题
当我登录时,我看到从 记录了以下消息CustomUserDetailsService.loadUserByUsername()
用户“[电子邮件受保护]”的角色:[USER]
所以看起来该用户已被分配 USER 角色。但是,当我尝试访问该控制器的操作时:
@Secured(['ROLE_USER', 'ROLE_ADMINISTRATOR'])
class MyProfileController {
def someAction = { // impl omitted }
}
我被弹回访问被拒绝页面。我非常确定用户已登录,因为访问被拒绝的页面包含诸如之类的标记
<sec:ifLoggedIn>
protected content
</sec:ifLoggedIn>
,并且显示了受保护的内容。因此,当执行控制器授权时,用户角色似乎与当前用户没有关联。日志消息表明 UserDetailsService
正常。
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
解决方案
解决方案是确保域类/数据库中的角色名称以“ROLE_”开头,根据注释参数。
致谢
该答案的所有功劳都归功于@BurtBeckwith 和@tim_yates,他们在评论中提供了解决方案。我正在将他们的评论转换为答案,因为未来的读者可能很容易错过他们的评论。
Solution
The solution is to make sure that the role names in the domain class/database begin with "ROLE_", as per the annotation parameters.
Acknowledgements
All credit for this answer goes to @BurtBeckwith and @tim_yates, who provided the solution in comments. I'm converting their comments to an answer, as future readers may easily miss their comments.