mirror of
https://github.com/spring-projects/spring-security.git
synced 2025-05-31 01:02:14 +00:00
SEC-1887: Improve extensibility of expression-based security classes
Introduces a new SecurityExpressionOperations interface which is implemented by SecurityExpressionRoot
This commit is contained in:
parent
b493afa18c
commit
0f9ee81df1
@ -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<T> implements SecurityExpressionHandler<T>, 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<T> 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<T> 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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
}
|
@ -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<String> 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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ public class AbstractSecurityExpressionHandlerTests {
|
||||
public void setUp() throws Exception {
|
||||
handler = new AbstractSecurityExpressionHandler<Object>() {
|
||||
@Override
|
||||
protected SecurityExpressionRoot createSecurityExpressionRoot(Authentication authentication, Object o) {
|
||||
protected SecurityExpressionOperations createSecurityExpressionRoot(Authentication authentication, Object o) {
|
||||
return new SecurityExpressionRoot(authentication) {};
|
||||
}
|
||||
};
|
||||
|
@ -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<FilterInvocation> {
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user