SEC-1245: Add role hierarchy support to expression handlers. Done.

This commit is contained in:
Luke Taylor 2009-09-15 17:17:21 +00:00
parent b531a81176
commit 1c4a809e09
4 changed files with 78 additions and 8 deletions

View File

@ -1,7 +1,10 @@
package org.springframework.security.access.expression;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.springframework.security.access.hierarchicalroles.RoleHierarchy;
import org.springframework.security.authentication.AuthenticationTrustResolver;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
@ -18,6 +21,9 @@ import org.springframework.security.core.authority.AuthorityUtils;
public abstract class SecurityExpressionRoot {
protected final Authentication authentication;
private AuthenticationTrustResolver trustResolver;
private RoleHierarchy roleHierarchy;
private Set<String> roles;
/** Allows "permitAll" expression */
public final boolean permitAll = true;
@ -32,17 +38,11 @@ public abstract class SecurityExpressionRoot {
}
public final boolean hasRole(String role) {
for (GrantedAuthority authority : authentication.getAuthorities()) {
if (role.equals(authority.getAuthority())) {
return true;
}
}
return false;
return getAuthoritySet().contains(role);
}
public final boolean hasAnyRole(String... roles) {
Set<String> roleSet = AuthorityUtils.authorityListToSet(authentication.getAuthorities());
Set<String> roleSet = getAuthoritySet();
for (String role : roles) {
if (roleSet.contains(role)) {
@ -88,4 +88,23 @@ public abstract class SecurityExpressionRoot {
public void setTrustResolver(AuthenticationTrustResolver trustResolver) {
this.trustResolver = trustResolver;
}
public void setRoleHierarchy(RoleHierarchy roleHierarchy) {
this.roleHierarchy = roleHierarchy;
}
private Set<String> getAuthoritySet() {
if (roles == null) {
roles = new HashSet<String>();
List<GrantedAuthority> userAuthorities = authentication.getAuthorities();
if (roleHierarchy != null) {
userAuthorities = roleHierarchy.getReachableGrantedAuthorities(userAuthorities);
}
roles = AuthorityUtils.authorityListToSet(userAuthorities);
}
return roles;
}
}

View File

@ -16,6 +16,7 @@ import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.security.access.PermissionEvaluator;
import org.springframework.security.access.expression.ExpressionUtils;
import org.springframework.security.access.hierarchicalroles.RoleHierarchy;
import org.springframework.security.authentication.AuthenticationTrustResolver;
import org.springframework.security.authentication.AuthenticationTrustResolverImpl;
import org.springframework.security.core.Authentication;
@ -37,6 +38,7 @@ public class DefaultMethodSecurityExpressionHandler implements MethodSecurityExp
private PermissionEvaluator permissionEvaluator = new DenyAllPermissionEvaluator();
private AuthenticationTrustResolver trustResolver = new AuthenticationTrustResolverImpl();
private ExpressionParser expressionParser = new SpelExpressionParser();
private RoleHierarchy roleHierarchy;
public DefaultMethodSecurityExpressionHandler() {
}
@ -50,6 +52,7 @@ public class DefaultMethodSecurityExpressionHandler implements MethodSecurityExp
MethodSecurityExpressionRoot root = new MethodSecurityExpressionRoot(auth);
root.setTrustResolver(trustResolver);
root.setPermissionEvaluator(permissionEvaluator);
root.setRoleHierarchy(roleHierarchy);
ctx.setRootObject(root);
return ctx;
@ -141,4 +144,7 @@ public class DefaultMethodSecurityExpressionHandler implements MethodSecurityExp
((MethodSecurityExpressionRoot)ctx.getRootObject().getValue()).setReturnObject(returnObject);
}
public void setRoleHierarchy(RoleHierarchy roleHierarchy) {
this.roleHierarchy = roleHierarchy;
}
}

View File

@ -0,0 +1,38 @@
package org.springframework.security.access.expression;
import static org.junit.Assert.*;
import java.util.List;
import org.junit.Test;
import org.springframework.security.access.hierarchicalroles.RoleHierarchy;
import org.springframework.security.authentication.TestingAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
/**
*
* @author Luke Taylor
* @version $Id$
* @since 3.0
*/
public class SecurityExpressionRootTests {
@Test
public void roleHierarchySupportIsCorrectlyUsedInEvaluatingRoles() throws Exception {
SecurityExpressionRoot root =
new SecurityExpressionRoot(new TestingAuthenticationToken("joe", "pass", "A", "B")) {};
root.setRoleHierarchy(new RoleHierarchy() {
public List<GrantedAuthority> getReachableGrantedAuthorities(List<GrantedAuthority> authorities) {
return AuthorityUtils.createAuthorityList("C");
}
});
assertTrue(root.hasRole("C"));
assertFalse(root.hasRole("A"));
assertFalse(root.hasRole("B"));
assertTrue(root.hasAnyRole("C", "A", "B"));
assertFalse(root.hasAnyRole("A", "B"));
}
}

View File

@ -5,6 +5,7 @@ import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.security.access.expression.SecurityExpressionRoot;
import org.springframework.security.access.hierarchicalroles.RoleHierarchy;
import org.springframework.security.authentication.AuthenticationTrustResolver;
import org.springframework.security.authentication.AuthenticationTrustResolverImpl;
import org.springframework.security.core.Authentication;
@ -22,6 +23,7 @@ public class DefaultWebSecurityExpressionHandler implements WebSecurityExpressio
private AuthenticationTrustResolver trustResolver = new AuthenticationTrustResolverImpl();
private ExpressionParser expressionParser = new SpelExpressionParser();
private RoleHierarchy roleHierarchy;
public ExpressionParser getExpressionParser() {
return expressionParser;
@ -31,8 +33,13 @@ public class DefaultWebSecurityExpressionHandler implements WebSecurityExpressio
StandardEvaluationContext ctx = new StandardEvaluationContext();
SecurityExpressionRoot root = new WebSecurityExpressionRoot(authentication, fi);
root.setTrustResolver(trustResolver);
root.setRoleHierarchy(roleHierarchy);
ctx.setRootObject(root);
return ctx;
}
public void setRoleHierarchy(RoleHierarchy roleHierarchy) {
this.roleHierarchy = roleHierarchy;
}
}