diff --git a/core/src/main/java/org/springframework/security/access/expression/AbstractSecurityExpressionHandler.java b/core/src/main/java/org/springframework/security/access/expression/AbstractSecurityExpressionHandler.java index a48801e9e2..9ec11f4766 100644 --- a/core/src/main/java/org/springframework/security/access/expression/AbstractSecurityExpressionHandler.java +++ b/core/src/main/java/org/springframework/security/access/expression/AbstractSecurityExpressionHandler.java @@ -10,8 +10,6 @@ import org.springframework.expression.spel.standard.SpelExpressionParser; import org.springframework.expression.spel.support.StandardEvaluationContext; import org.springframework.security.access.PermissionEvaluator; 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,7 +20,6 @@ import org.springframework.security.core.Authentication; * @since 3.1 */ public abstract class AbstractSecurityExpressionHandler implements SecurityExpressionHandler, ApplicationContextAware { - private final AuthenticationTrustResolver trustResolver = new AuthenticationTrustResolverImpl(); private final ExpressionParser expressionParser = new SpelExpressionParser(); private BeanResolver br; private RoleHierarchy roleHierarchy; @@ -34,17 +31,14 @@ public abstract class AbstractSecurityExpressionHandler implements SecurityEx /** * Invokes the internal template methods to create {@code StandardEvaluationContext} and {@code SecurityExpressionRoot} - * objects. The root object will be injected with references to the application context, the {@code roleHierarchy} - * if set, and an {@code AuthenticationTrustResolver}. + * objects. * * @param authentication the current authentication object * @param invocation the invocation (filter, method, channel) * @return the context object for use in evaluating the expression, populated with a suitable root object. */ public final EvaluationContext createEvaluationContext(Authentication authentication, T invocation) { - SecurityExpressionRoot root = createSecurityExpressionRoot(authentication, invocation); - root.setTrustResolver(trustResolver); - root.setRoleHierarchy(roleHierarchy); + SecurityExpressionOperations root = createSecurityExpressionRoot(authentication, invocation); StandardEvaluationContext ctx = createEvaluationContextInternal(authentication, invocation); ctx.setBeanResolver(br); ctx.setRootObject(root); @@ -73,8 +67,12 @@ public abstract class AbstractSecurityExpressionHandler implements SecurityEx * @param invocation the invocation (filter, method, channel) * @return the object wh */ - protected abstract SecurityExpressionRoot createSecurityExpressionRoot(Authentication authentication, T invocation); + protected abstract SecurityExpressionOperations createSecurityExpressionRoot(Authentication authentication, T invocation); + protected RoleHierarchy getRoleHierarchy() { + return roleHierarchy; + } + public void setRoleHierarchy(RoleHierarchy roleHierarchy) { this.roleHierarchy = roleHierarchy; } diff --git a/core/src/main/java/org/springframework/security/access/expression/SecurityExpressionOperations.java b/core/src/main/java/org/springframework/security/access/expression/SecurityExpressionOperations.java new file mode 100644 index 0000000000..b5bd0011da --- /dev/null +++ b/core/src/main/java/org/springframework/security/access/expression/SecurityExpressionOperations.java @@ -0,0 +1,30 @@ +package org.springframework.security.access.expression; + +public interface SecurityExpressionOperations { + + public abstract boolean hasAuthority(String authority); + + public abstract boolean hasAnyAuthority(String... authorities); + + public abstract boolean hasRole(String role); + + public abstract boolean hasAnyRole(String... roles); + + public abstract boolean permitAll(); + + public abstract boolean denyAll(); + + public abstract boolean isAnonymous(); + + public abstract boolean isAuthenticated(); + + public abstract boolean isRememberMe(); + + public abstract boolean isFullyAuthenticated(); + + public abstract boolean hasPermission(Object target, Object permission); + + public abstract boolean hasPermission(Object targetId, String targetType, + Object permission); + +} \ No newline at end of file diff --git a/core/src/main/java/org/springframework/security/access/expression/SecurityExpressionRoot.java b/core/src/main/java/org/springframework/security/access/expression/SecurityExpressionRoot.java index 3c7b9658fd..eb190b3384 100644 --- a/core/src/main/java/org/springframework/security/access/expression/SecurityExpressionRoot.java +++ b/core/src/main/java/org/springframework/security/access/expression/SecurityExpressionRoot.java @@ -20,7 +20,7 @@ import org.springframework.security.core.authority.AuthorityUtils; * @author Luke Taylor * @since 3.0 */ -public abstract class SecurityExpressionRoot { +public abstract class SecurityExpressionRoot implements SecurityExpressionOperations { protected final Authentication authentication; private AuthenticationTrustResolver trustResolver; private RoleHierarchy roleHierarchy; @@ -45,19 +45,35 @@ public abstract class SecurityExpressionRoot { this.authentication = a; } - public final boolean hasAuthority(String authority) { + /* (non-Javadoc) + * @see org.springframework.security.access.expression.SecurityExpressionOperations#hasAuthority(java.lang.String) + */ + @Override + public final boolean hasAuthority(String authority) { return hasRole(authority); } - public final boolean hasAnyAuthority(String... authorities) { + /* (non-Javadoc) + * @see org.springframework.security.access.expression.SecurityExpressionOperations#hasAnyAuthority(java.lang.String) + */ + @Override + public final boolean hasAnyAuthority(String... authorities) { return hasAnyRole(authorities); } - public final boolean hasRole(String role) { + /* (non-Javadoc) + * @see org.springframework.security.access.expression.SecurityExpressionOperations#hasRole(java.lang.String) + */ + @Override + public final boolean hasRole(String role) { return getAuthoritySet().contains(role); } - public final boolean hasAnyRole(String... roles) { + /* (non-Javadoc) + * @see org.springframework.security.access.expression.SecurityExpressionOperations#hasAnyRole(java.lang.String) + */ + @Override + public final boolean hasAnyRole(String... roles) { Set roleSet = getAuthoritySet(); for (String role : roles) { @@ -73,27 +89,51 @@ public abstract class SecurityExpressionRoot { return authentication; } - public final boolean permitAll() { + /* (non-Javadoc) + * @see org.springframework.security.access.expression.SecurityExpressionOperations#permitAll() + */ + @Override + public final boolean permitAll() { return true; } - public final boolean denyAll() { + /* (non-Javadoc) + * @see org.springframework.security.access.expression.SecurityExpressionOperations#denyAll() + */ + @Override + public final boolean denyAll() { return false; } - public final boolean isAnonymous() { + /* (non-Javadoc) + * @see org.springframework.security.access.expression.SecurityExpressionOperations#isAnonymous() + */ + @Override + public final boolean isAnonymous() { return trustResolver.isAnonymous(authentication); } - public final boolean isAuthenticated() { + /* (non-Javadoc) + * @see org.springframework.security.access.expression.SecurityExpressionOperations#isAuthenticated() + */ + @Override + public final boolean isAuthenticated() { return !isAnonymous(); } - public final boolean isRememberMe() { + /* (non-Javadoc) + * @see org.springframework.security.access.expression.SecurityExpressionOperations#isRememberMe() + */ + @Override + public final boolean isRememberMe() { return trustResolver.isRememberMe(authentication); } - public final boolean isFullyAuthenticated() { + /* (non-Javadoc) + * @see org.springframework.security.access.expression.SecurityExpressionOperations#isFullyAuthenticated() + */ + @Override + public final boolean isFullyAuthenticated() { return !trustResolver.isAnonymous(authentication) && !trustResolver.isRememberMe(authentication); } @@ -124,11 +164,19 @@ public abstract class SecurityExpressionRoot { return roles; } - public boolean hasPermission(Object target, Object permission) { + /* (non-Javadoc) + * @see org.springframework.security.access.expression.SecurityExpressionOperations#hasPermission(java.lang.Object, java.lang.Object) + */ + @Override + public boolean hasPermission(Object target, Object permission) { return permissionEvaluator.hasPermission(authentication, target, permission); } - public boolean hasPermission(Object targetId, String targetType, Object permission) { + /* (non-Javadoc) + * @see org.springframework.security.access.expression.SecurityExpressionOperations#hasPermission(java.lang.Object, java.lang.String, java.lang.Object) + */ + @Override + public boolean hasPermission(Object targetId, String targetType, Object permission) { return permissionEvaluator.hasPermission(authentication, (Serializable)targetId, targetType, permission); } diff --git a/core/src/main/java/org/springframework/security/access/expression/method/DefaultMethodSecurityExpressionHandler.java b/core/src/main/java/org/springframework/security/access/expression/method/DefaultMethodSecurityExpressionHandler.java index 6de580206d..f525ca3398 100644 --- a/core/src/main/java/org/springframework/security/access/expression/method/DefaultMethodSecurityExpressionHandler.java +++ b/core/src/main/java/org/springframework/security/access/expression/method/DefaultMethodSecurityExpressionHandler.java @@ -1,7 +1,10 @@ package org.springframework.security.access.expression.method; import java.lang.reflect.Array; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; import org.aopalliance.intercept.MethodInvocation; import org.apache.commons.logging.Log; @@ -12,11 +15,11 @@ import org.springframework.expression.EvaluationContext; import org.springframework.expression.Expression; import org.springframework.expression.spel.support.StandardEvaluationContext; import org.springframework.security.access.PermissionCacheOptimizer; -import org.springframework.security.access.PermissionEvaluator; import org.springframework.security.access.expression.AbstractSecurityExpressionHandler; -import org.springframework.security.access.expression.DenyAllPermissionEvaluator; import org.springframework.security.access.expression.ExpressionUtils; -import org.springframework.security.access.expression.SecurityExpressionRoot; +import org.springframework.security.access.expression.SecurityExpressionOperations; +import org.springframework.security.authentication.AuthenticationTrustResolver; +import org.springframework.security.authentication.AuthenticationTrustResolverImpl; import org.springframework.security.core.Authentication; /** @@ -31,6 +34,7 @@ public class DefaultMethodSecurityExpressionHandler extends AbstractSecurityExpr protected final Log logger = LogFactory.getLog(getClass()); + private final AuthenticationTrustResolver trustResolver = new AuthenticationTrustResolverImpl(); private ParameterNameDiscoverer parameterNameDiscoverer = new LocalVariableTableParameterNameDiscoverer(); private PermissionCacheOptimizer permissionCacheOptimizer = null; @@ -45,10 +49,12 @@ public class DefaultMethodSecurityExpressionHandler extends AbstractSecurityExpr } @Override - protected SecurityExpressionRoot createSecurityExpressionRoot(Authentication authentication, MethodInvocation invocation) { + protected SecurityExpressionOperations createSecurityExpressionRoot(Authentication authentication, MethodInvocation invocation) { MethodSecurityExpressionRoot root = new MethodSecurityExpressionRoot(authentication); root.setThis(invocation.getThis()); root.setPermissionEvaluator(getPermissionEvaluator()); + root.setTrustResolver(trustResolver); + root.setRoleHierarchy(getRoleHierarchy()); return root; } diff --git a/core/src/test/java/org/springframework/security/access/expression/AbstractSecurityExpressionHandlerTests.java b/core/src/test/java/org/springframework/security/access/expression/AbstractSecurityExpressionHandlerTests.java index 42ceadf9b0..741362c7d0 100644 --- a/core/src/test/java/org/springframework/security/access/expression/AbstractSecurityExpressionHandlerTests.java +++ b/core/src/test/java/org/springframework/security/access/expression/AbstractSecurityExpressionHandlerTests.java @@ -23,7 +23,7 @@ public class AbstractSecurityExpressionHandlerTests { public void setUp() throws Exception { handler = new AbstractSecurityExpressionHandler() { @Override - protected SecurityExpressionRoot createSecurityExpressionRoot(Authentication authentication, Object o) { + protected SecurityExpressionOperations createSecurityExpressionRoot(Authentication authentication, Object o) { return new SecurityExpressionRoot(authentication) {}; } }; diff --git a/web/src/main/java/org/springframework/security/web/access/expression/DefaultWebSecurityExpressionHandler.java b/web/src/main/java/org/springframework/security/web/access/expression/DefaultWebSecurityExpressionHandler.java index d42599d809..380ee3b2d6 100644 --- a/web/src/main/java/org/springframework/security/web/access/expression/DefaultWebSecurityExpressionHandler.java +++ b/web/src/main/java/org/springframework/security/web/access/expression/DefaultWebSecurityExpressionHandler.java @@ -1,7 +1,9 @@ package org.springframework.security.web.access.expression; import org.springframework.security.access.expression.AbstractSecurityExpressionHandler; -import org.springframework.security.access.expression.SecurityExpressionRoot; +import org.springframework.security.access.expression.SecurityExpressionOperations; +import org.springframework.security.authentication.AuthenticationTrustResolver; +import org.springframework.security.authentication.AuthenticationTrustResolverImpl; import org.springframework.security.core.Authentication; import org.springframework.security.web.FilterInvocation; @@ -11,11 +13,15 @@ import org.springframework.security.web.FilterInvocation; * @since 3.0 */ public class DefaultWebSecurityExpressionHandler extends AbstractSecurityExpressionHandler { + + private final AuthenticationTrustResolver trustResolver = new AuthenticationTrustResolverImpl(); @Override - protected SecurityExpressionRoot createSecurityExpressionRoot(Authentication authentication, FilterInvocation fi) { + protected SecurityExpressionOperations createSecurityExpressionRoot(Authentication authentication, FilterInvocation fi) { WebSecurityExpressionRoot root = new WebSecurityExpressionRoot(authentication, fi); root.setPermissionEvaluator(getPermissionEvaluator()); + root.setTrustResolver(trustResolver); + root.setRoleHierarchy(getRoleHierarchy()); return root; } }