SEC-1576: Parameterize the secured object type in AccessDecisionVoter.

This commit is contained in:
Luke Taylor 2010-12-16 15:21:22 +00:00
parent 85d685f7d3
commit c8820166c8
13 changed files with 45 additions and 46 deletions

View File

@ -2,6 +2,7 @@
dependencies {
compile project(':spring-security-core'),
'aopalliance:aopalliance:1.0',
"net.sf.ehcache:ehcache:$ehcacheVersion",
"org.springframework:spring-aop:$springVersion",
"org.springframework:spring-context:$springVersion",

View File

@ -20,6 +20,7 @@ import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import org.aopalliance.intercept.MethodInvocation;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.security.access.AuthorizationServiceException;
@ -148,7 +149,7 @@ public class AclEntryVoter extends AbstractAclVoter {
return (attribute.getAttribute() != null) && attribute.getAttribute().equals(getProcessConfigAttribute());
}
public int vote(Authentication authentication, Object object, Collection<ConfigAttribute> attributes) {
public int vote(Authentication authentication, MethodInvocation object, Collection<ConfigAttribute> attributes) {
for(ConfigAttribute attr : attributes) {

View File

@ -22,16 +22,14 @@ import org.springframework.security.core.Authentication;
/**
* Indicates a class is responsible for voting on authorization decisions.
*
* <p>
* The coordination of voting (ie polling <code>AccessDecisionVoter</code>s,
* The coordination of voting (ie polling {@code AccessDecisionVoter}s,
* tallying their responses, and making the final authorization decision) is
* performed by an {@link org.springframework.security.access.AccessDecisionManager}.
* </p>
*
* @author Ben Alex
*/
public interface AccessDecisionVoter {
public interface AccessDecisionVoter<S> {
//~ Static fields/initializers =====================================================================================
int ACCESS_GRANTED = 1;
@ -41,20 +39,20 @@ public interface AccessDecisionVoter {
//~ Methods ========================================================================================================
/**
* Indicates whether this <code>AccessDecisionVoter</code> is able to vote on the passed
* <code>ConfigAttribute</code>.<p>This allows the <code>AbstractSecurityInterceptor</code> to check every
* configuration attribute can be consumed by the configured <code>AccessDecisionManager</code> and/or
* <code>RunAsManager</code> and/or <code>AfterInvocationManager</code>.</p>
* Indicates whether this {@code AccessDecisionVoter} is able to vote on the passed {@code ConfigAttribute}.
* <p>
* This allows the {@code AbstractSecurityInterceptor} to check every configuration attribute can be consumed by
* the configured {@code AccessDecisionManager} and/or {@code RunAsManager} and/or {@code AfterInvocationManager}.
*
* @param attribute a configuration attribute that has been configured against the
* <code>AbstractSecurityInterceptor</code>
* {@code AbstractSecurityInterceptor}
*
* @return true if this <code>AccessDecisionVoter</code> can support the passed configuration attribute
* @return true if this {@code AccessDecisionVoter} can support the passed configuration attribute
*/
boolean supports(ConfigAttribute attribute);
/**
* Indicates whether the <code>AccessDecisionVoter</code> implementation is able to provide access control
* Indicates whether the {@code AccessDecisionVoter} implementation is able to provide access control
* votes for the indicated secured object type.
*
* @param clazz the class that is being queried
@ -65,26 +63,27 @@ public interface AccessDecisionVoter {
/**
* Indicates whether or not access is granted.
* <p>The decision must be affirmative (<code>ACCESS_GRANTED</code>), negative (<code>ACCESS_DENIED</code>)
* or the <code>AccessDecisionVoter</code> can abstain (<code>ACCESS_ABSTAIN</code>) from voting.
* <p>
* The decision must be affirmative ({@code ACCESS_GRANTED}), negative ({@code ACCESS_DENIED})
* or the {@code AccessDecisionVoter} can abstain ({@code ACCESS_ABSTAIN}) from voting.
* Under no circumstances should implementing classes return any other value. If a weighting of results is desired,
* this should be handled in a custom {@link org.springframework.security.access.AccessDecisionManager} instead.
* </p>
* <p>Unless an <code>AccessDecisionVoter</code> is specifically intended to vote on an access control
* <p>
* Unless an {@code AccessDecisionVoter} is specifically intended to vote on an access control
* decision due to a passed method invocation or configuration attribute parameter, it must return
* <code>ACCESS_ABSTAIN</code>. This prevents the coordinating <code>AccessDecisionManager</code> from counting
* votes from those <code>AccessDecisionVoter</code>s without a legitimate interest in the access control
* {@code ACCESS_ABSTAIN}. This prevents the coordinating {@code AccessDecisionManager} from counting
* votes from those {@code AccessDecisionVoter}s without a legitimate interest in the access control
* decision.
* </p>
* <p>Whilst the method invocation is passed as a parameter to maximise flexibility in making access
* control decisions, implementing classes must never modify the behaviour of the method invocation (such as
* calling <Code>MethodInvocation.proceed()</code>).</p>
* <p>
* Whilst the secured object (such as a {@code MethodInvocation}) is passed as a parameter to maximise flexibility
* in making access control decisions, implementing classes should not modify it or cause the represented invocation
* to take place (for example, by calling {@code MethodInvocation.proceed()}).
*
* @param authentication the caller invoking the method
* @param object the secured object
* @param attributes the configuration attributes associated with the method being invoked
* @param authentication the caller making the invocation
* @param object the secured object being invoked
* @param attributes the configuration attributes associated with the secured object
*
* @return either {@link #ACCESS_GRANTED}, {@link #ACCESS_ABSTAIN} or {@link #ACCESS_DENIED}
*/
int vote(Authentication authentication, Object object, Collection<ConfigAttribute> attributes);
int vote(Authentication authentication, S object, Collection<ConfigAttribute> attributes);
}

View File

@ -13,7 +13,7 @@ import org.springframework.security.core.GrantedAuthority;
* @author Ryan Heaton
* @since 2.0
*/
public class Jsr250Voter implements AccessDecisionVoter {
public class Jsr250Voter implements AccessDecisionVoter<Object> {
/**
* The specified config attribute is supported if its an instance of a {@link Jsr250SecurityConfig}.

View File

@ -21,7 +21,7 @@ import org.springframework.security.core.Authentication;
* @author Luke Taylor
* @since 3.0
*/
public class PreInvocationAuthorizationAdviceVoter implements AccessDecisionVoter {
public class PreInvocationAuthorizationAdviceVoter implements AccessDecisionVoter<MethodInvocation> {
protected final Log logger = LogFactory.getLog(getClass());
private final PreInvocationAuthorizationAdvice preAdvice;
@ -38,7 +38,7 @@ public class PreInvocationAuthorizationAdviceVoter implements AccessDecisionVote
return clazz.isAssignableFrom(MethodInvocation.class);
}
public int vote(Authentication authentication, Object object, Collection<ConfigAttribute> attributes) {
public int vote(Authentication authentication, MethodInvocation method, Collection<ConfigAttribute> attributes) {
// Find prefilter and preauth (or combined) attributes
// if both null, abstain
@ -51,7 +51,7 @@ public class PreInvocationAuthorizationAdviceVoter implements AccessDecisionVote
return ACCESS_ABSTAIN;
}
boolean allowed = preAdvice.before(authentication, (MethodInvocation)object, preAttr);
boolean allowed = preAdvice.before(authentication, method, preAttr);
return allowed ? ACCESS_GRANTED : ACCESS_DENIED;
}

View File

@ -26,18 +26,17 @@ import org.springframework.util.Assert;
*
* @author Ben Alex
*/
public abstract class AbstractAclVoter implements AccessDecisionVoter {
public abstract class AbstractAclVoter implements AccessDecisionVoter<MethodInvocation> {
//~ Instance fields ================================================================================================
private Class<?> processDomainObjectClass;
//~ Methods ========================================================================================================
protected Object getDomainObjectInstance(Object secureObject) {
protected Object getDomainObjectInstance(MethodInvocation invocation) {
Object[] args;
Class<?>[] params;
MethodInvocation invocation = (MethodInvocation) secureObject;
params = invocation.getMethod().getParameterTypes();
args = invocation.getArguments();
@ -47,7 +46,7 @@ public abstract class AbstractAclVoter implements AccessDecisionVoter {
}
}
throw new AuthorizationServiceException("Secure object: " + secureObject
throw new AuthorizationServiceException("MethodInvocation: " + invocation
+ " did not provide any argument of type: " + processDomainObjectClass);
}

View File

@ -41,7 +41,7 @@ import org.springframework.util.Assert;
*
* @author Ben Alex
*/
public class AuthenticatedVoter implements AccessDecisionVoter {
public class AuthenticatedVoter implements AccessDecisionVoter<Object> {
//~ Static fields/initializers =====================================================================================
public static final String IS_AUTHENTICATED_FULLY = "IS_AUTHENTICATED_FULLY";
@ -77,9 +77,9 @@ public class AuthenticatedVoter implements AccessDecisionVoter {
/**
* This implementation supports any type of class, because it does not query the presented secure object.
*
* @param clazz the secure object
* @param clazz the secure object type
*
* @return always <code>true</code>
* @return always {@code true}
*/
public boolean supports(Class<?> clazz) {
return true;

View File

@ -49,7 +49,7 @@ import org.springframework.security.core.GrantedAuthority;
* @author Ben Alex
* @author colin sampaleanu
*/
public class RoleVoter implements AccessDecisionVoter {
public class RoleVoter implements AccessDecisionVoter<Object> {
//~ Instance fields ================================================================================================
private String rolePrefix = "ROLE_";

View File

@ -150,7 +150,7 @@ public class AbstractAccessDecisionManagerTests extends TestCase {
}
}
private class MockStringOnlyVoter implements AccessDecisionVoter {
private class MockStringOnlyVoter implements AccessDecisionVoter<Object> {
public boolean supports(Class<?> clazz) {
return String.class.isAssignableFrom(clazz);
}

View File

@ -19,7 +19,7 @@ public class AbstractAclVoterTests {
public boolean supports(ConfigAttribute attribute) {
return false;
}
public int vote(Authentication authentication, Object object, Collection<ConfigAttribute> attributes) {
public int vote(Authentication authentication, MethodInvocation object, Collection<ConfigAttribute> attributes) {
return 0;
}
};

View File

@ -32,7 +32,7 @@ import java.util.Iterator;
*
* @author Ben Alex
*/
public class DenyAgainVoter implements AccessDecisionVoter {
public class DenyAgainVoter implements AccessDecisionVoter<Object> {
// ~ Methods
// ========================================================================================================

View File

@ -30,7 +30,7 @@ import java.util.Iterator;
*
* @author Ben Alex
*/
public class DenyVoter implements AccessDecisionVoter {
public class DenyVoter implements AccessDecisionVoter<Object> {
//~ Methods ========================================================================================================
public boolean supports(ConfigAttribute attribute) {

View File

@ -15,12 +15,12 @@ import org.springframework.security.web.FilterInvocation;
* @author Luke Taylor
* @since 3.0
*/
public class WebExpressionVoter implements AccessDecisionVoter {
public class WebExpressionVoter implements AccessDecisionVoter<FilterInvocation> {
private SecurityExpressionHandler<FilterInvocation> expressionHandler = new DefaultWebSecurityExpressionHandler();
public int vote(Authentication authentication, Object object, Collection<ConfigAttribute> attributes) {
public int vote(Authentication authentication, FilterInvocation fi, Collection<ConfigAttribute> attributes) {
assert authentication != null;
assert object != null;
assert fi != null;
assert attributes != null;
WebExpressionConfigAttribute weca = findConfigAttribute(attributes);
@ -29,7 +29,6 @@ public class WebExpressionVoter implements AccessDecisionVoter {
return ACCESS_ABSTAIN;
}
FilterInvocation fi = (FilterInvocation)object;
EvaluationContext ctx = expressionHandler.createEvaluationContext(authentication, fi);
return ExpressionUtils.evaluateAsBoolean(weca.getAuthorizeExpression(), ctx) ?