【发布时间】:2011-11-27 06:44:44
【问题描述】:
背景
我正在使用 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() 的以下消息
用户“a5511120@nepwk.com”的角色:[USER]
所以看起来用户已被分配了 USER 角色。但是,当我尝试访问此控制器的操作时:
@Secured(['ROLE_USER', 'ROLE_ADMINISTRATOR'])
class MyProfileController {
def someAction = { // impl omitted }
}
我被退回到拒绝访问页面。我很确定用户已登录,因为拒绝访问页面包含诸如
之类的标记<sec:ifLoggedIn>
protected content
</sec:ifLoggedIn>
并显示受保护的内容。因此,当执行控制器授权时,似乎 USER 角色与当前用户没有关联。日志消息表明UserDetailsService 正常。
【问题讨论】:
-
println中的USER和ROLE_USER一样吗?
-
getCurrentUser()是供用户使用的实用方法,但插件或 Spring Security 未使用,因此与此问题无关。尝试在 Log4j 配置中设置“org.springframework.security”类别进行调试 - Spring Security 擅长转储有关身份验证失败的详细信息。 -
啊,刚刚看到蒂姆的问题——大概就是这样。角色必须以“ROLE_”开头,否则
RoleVoter会忽略它们。 -
@BurtBeckwith @tim_yates 你是说
GrantedAuthority.authority应该返回一个以“ROLE_”开头的字符串吗? -
是的,总是 - 角色需要一个前缀来将它们与 IS_AUTHENTICATED_FULLY 等非角色标记区分开来,并且它目前无法配置为“ROLE_”以外的任何内容。当然,您可以在 UI 中将它们转换为更美观的字符串。
标签: grails groovy spring-security