mirror of
https://github.com/spring-projects/spring-security.git
synced 2025-02-26 09:24:53 +00:00
SEC-1576: Parameterize the secured object type in AccessDecisionVoter.
This commit is contained in:
parent
85d685f7d3
commit
c8820166c8
@ -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",
|
||||
|
@ -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) {
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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}.
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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_";
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
};
|
||||
|
@ -32,7 +32,7 @@ import java.util.Iterator;
|
||||
*
|
||||
* @author Ben Alex
|
||||
*/
|
||||
public class DenyAgainVoter implements AccessDecisionVoter {
|
||||
public class DenyAgainVoter implements AccessDecisionVoter<Object> {
|
||||
// ~ Methods
|
||||
// ========================================================================================================
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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) ?
|
||||
|
Loading…
x
Reference in New Issue
Block a user