我们的系统需要允许用户成为多个组织的成员,并为每个组织拥有不同的角色。我的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身份验证。我误读了文档吗?或者我是否错误地实施了选民?