我们的系统需要允许用户成为多个组织的成员,并且每个组织具有不同的角色。我的 UserRole 类已修改为以下内容:
class UserRole implements Serializable {
User user
Role role
Organization organization
}
为了使它工作,我必须创建一个自定义投票器,如下所示:
class OrganizationRoleVoter extends RoleVoter {
@Override
public int vote(Authentication authentication, Object object, Collection<ConfigAttribute> attributes) {
int result = ACCESS_ABSTAIN
Collection<? extends GrantedAuthority> authorities = extractAuthorities(authentication)
GrailsWebRequest request = RequestContextHolder.currentRequestAttributes()
Organization selectedOrganization = (Organization) request.session.getAttribute("selectedOrganizationSession")
attributes.each {ConfigAttribute attribute ->
if (this.supports(attribute)) {
result = ACCESS_DENIED
for (GrantedAuthority authority : authorities) {
if (attribute.attribute.equals(authority.authority)) {
def user = User.findByUsername(authentication.name)
def role = Role.findByAuthority(authority.authority)
if (UserRole.findByUserAndOrganizationAndRole(user, selectedOrganization, role)) {
result = ACCESS_GRANTED
break
}
}
}
}
}
return result
}
Collection<? extends GrantedAuthority> extractAuthorities(Authentication authentication) {
return authentication.getAuthorities();
}
}
我们遇到的问题是Remember Me cookie。如果在某些请求期间(不是全部)使用它,应用程序将强制进行完整身份验证。我只看到 ajax 请求会发生这种情况,但我们的应用程序是 90% 的 ajax,所以我不能肯定地说就是这种情况。但是,我将所有用户级控制器都注释如下:
@Secured(['ROLE_USER', 'IS_AUTHENTICATED_REMEMBERED'])
(每次使用都需要 ROLE_USER 角色,必要时可以有其他角色)。
这是配置:
grails.plugins.springsecurity.voterNames = [
'organizationRoleVoter', 'authenticatedVoter'
]
grails.plugins.springsecurity.logout.handlerNames =
['rememberMeServices',
'securityContextLogoutHandler',
'securityEventListener']
所以我现在不确定如果我告诉它允许记住我的 cookie 身份验证,为什么应用程序需要完整的身份验证。我误读了文档吗?还是我错误地执行了选民?