Reputation: 35904
Taking the suggestion provided here, I've implemented my own RoleVoter classes that extends RoleVoter and the additional check I need to add is that the User, Role, and Organization all line up based on the Organization I have stored in the session.
I have the following UserRole class:
class UserRole implements Serializable {
User user
Role role
Organization organization
....
}
And this is my OrganizationRoleVoter class:
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)
attributes.each {ConfigAttribute attribute ->
if (this.supports(attribute)) {
result = ACCESS_DENIED
authorities.each {GrantedAuthority authority ->
//TODO this should also check the chosen organization
if (attribute.attribute.equals(authority.authority)) {
return ACCESS_GRANTED
}
}
}
}
return result
}
Collection<? extends GrantedAuthority> extractAuthorities(Authentication authentication) {
return authentication.getAuthorities();
}
}
As you can see in my TODO, this is where I need to also say "is the authority that is being granted here also in line with the organization that I've placed in the session. Really at a loss on how to achieve this.
Upvotes: 2
Views: 657
Reputation: 35904
Here is how I've solved it thus far. This seems to work but I'm always open for improvements:
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();
}
}
Upvotes: 2