Polish AOP Structure
- Changed from MethodMatcher to Pointcut since authorization annotations also can be attached to classes - Adjusted advice to extend Before or AfterAdvice - Adjusted advice to extend PointcutAdvisor so that it can share its Pointcut - Adjusted advice to extend AopInfrastructureBean to align with old advice classes Issue gh-9289
This commit is contained in:
@@ -19,6 +19,7 @@ package org.springframework.security.authorization.method;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.springframework.aop.MethodMatcher;
|
||||
import org.springframework.aop.Pointcut;
|
||||
import org.springframework.security.access.AccessDeniedException;
|
||||
import org.springframework.security.authorization.AuthorizationManager;
|
||||
import org.springframework.security.core.Authentication;
|
||||
@@ -31,24 +32,24 @@ import org.springframework.util.Assert;
|
||||
*
|
||||
* @param <T> the type of object that the authorization check is being done one.
|
||||
* @author Evgeniy Cheban
|
||||
* @author Josh Cummings
|
||||
* @since 5.5
|
||||
*/
|
||||
public final class AuthorizationManagerMethodAfterAdvice<T> implements AuthorizationMethodAfterAdvice<T> {
|
||||
|
||||
private final MethodMatcher methodMatcher;
|
||||
private final Pointcut pointcut;
|
||||
|
||||
private final AuthorizationManager<T> authorizationManager;
|
||||
|
||||
/**
|
||||
* Creates an instance.
|
||||
* @param methodMatcher the {@link MethodMatcher} to use
|
||||
* @param pointcut the {@link Pointcut} to use
|
||||
* @param authorizationManager the {@link AuthorizationManager} to use
|
||||
*/
|
||||
public AuthorizationManagerMethodAfterAdvice(MethodMatcher methodMatcher,
|
||||
AuthorizationManager<T> authorizationManager) {
|
||||
Assert.notNull(methodMatcher, "methodMatcher cannot be null");
|
||||
public AuthorizationManagerMethodAfterAdvice(Pointcut pointcut, AuthorizationManager<T> authorizationManager) {
|
||||
Assert.notNull(pointcut, "pointcut cannot be null");
|
||||
Assert.notNull(authorizationManager, "authorizationManager cannot be null");
|
||||
this.methodMatcher = methodMatcher;
|
||||
this.pointcut = pointcut;
|
||||
this.authorizationManager = authorizationManager;
|
||||
}
|
||||
|
||||
@@ -65,9 +66,12 @@ public final class AuthorizationManagerMethodAfterAdvice<T> implements Authoriza
|
||||
return returnedObject;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public MethodMatcher getMethodMatcher() {
|
||||
return this.methodMatcher;
|
||||
public Pointcut getPointcut() {
|
||||
return this.pointcut;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ package org.springframework.security.authorization.method;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.springframework.aop.MethodMatcher;
|
||||
import org.springframework.aop.Pointcut;
|
||||
import org.springframework.security.access.AccessDeniedException;
|
||||
import org.springframework.security.authorization.AuthorizationManager;
|
||||
import org.springframework.security.core.Authentication;
|
||||
@@ -31,24 +32,24 @@ import org.springframework.util.Assert;
|
||||
*
|
||||
* @param <T> the type of object that the authorization check is being done one.
|
||||
* @author Evgeniy Cheban
|
||||
* @author Josh Cummings
|
||||
* @since 5.5
|
||||
*/
|
||||
public final class AuthorizationManagerMethodBeforeAdvice<T> implements AuthorizationMethodBeforeAdvice<T> {
|
||||
|
||||
private final MethodMatcher methodMatcher;
|
||||
private final Pointcut pointcut;
|
||||
|
||||
private final AuthorizationManager<T> authorizationManager;
|
||||
|
||||
/**
|
||||
* Creates an instance.
|
||||
* @param methodMatcher the {@link MethodMatcher} to use
|
||||
* @param pointcut the {@link Pointcut} to use
|
||||
* @param authorizationManager the {@link AuthorizationManager} to use
|
||||
*/
|
||||
public AuthorizationManagerMethodBeforeAdvice(MethodMatcher methodMatcher,
|
||||
AuthorizationManager<T> authorizationManager) {
|
||||
Assert.notNull(methodMatcher, "methodMatcher cannot be null");
|
||||
public AuthorizationManagerMethodBeforeAdvice(Pointcut pointcut, AuthorizationManager<T> authorizationManager) {
|
||||
Assert.notNull(pointcut, "pointcut cannot be null");
|
||||
Assert.notNull(authorizationManager, "authorizationManager cannot be null");
|
||||
this.methodMatcher = methodMatcher;
|
||||
this.pointcut = pointcut;
|
||||
this.authorizationManager = authorizationManager;
|
||||
}
|
||||
|
||||
@@ -64,9 +65,12 @@ public final class AuthorizationManagerMethodBeforeAdvice<T> implements Authoriz
|
||||
this.authorizationManager.verify(authentication, object);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public MethodMatcher getMethodMatcher() {
|
||||
return this.methodMatcher;
|
||||
public Pointcut getPointcut() {
|
||||
return this.pointcut;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,30 +18,40 @@ package org.springframework.security.authorization.method;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.aopalliance.aop.Advice;
|
||||
import org.aopalliance.intercept.MethodInvocation;
|
||||
|
||||
import org.springframework.aop.ClassFilter;
|
||||
import org.springframework.aop.Pointcut;
|
||||
import org.springframework.aop.AfterAdvice;
|
||||
import org.springframework.aop.PointcutAdvisor;
|
||||
import org.springframework.aop.framework.AopInfrastructureBean;
|
||||
import org.springframework.security.core.Authentication;
|
||||
|
||||
/**
|
||||
* An Authorization advice that can determine if an {@link Authentication} has access to
|
||||
* the returned object from the {@link MethodInvocation}. The {@link #getMethodMatcher()}
|
||||
* An {@link Advice} which can determine if an {@link Authentication} has
|
||||
* access to the returned object from the {@link MethodInvocation}. {@link #getPointcut()}
|
||||
* describes when the advice applies for the method.
|
||||
*
|
||||
* @param <T> the type of object that the authorization check is being done one.
|
||||
* @author Evgeniy Cheban
|
||||
* @author Josh Cummings
|
||||
* @since 5.5
|
||||
*/
|
||||
public interface AuthorizationMethodAfterAdvice<T> extends Pointcut {
|
||||
public interface AuthorizationMethodAfterAdvice<T> extends AfterAdvice, PointcutAdvisor, AopInfrastructureBean {
|
||||
|
||||
/**
|
||||
* Returns the default {@link ClassFilter}.
|
||||
* @return the {@link ClassFilter#TRUE} to use
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
default ClassFilter getClassFilter() {
|
||||
return ClassFilter.TRUE;
|
||||
default boolean isPerInstance() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
default Advice getAdvice() {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -18,28 +18,38 @@ package org.springframework.security.authorization.method;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.springframework.aop.ClassFilter;
|
||||
import org.springframework.aop.Pointcut;
|
||||
import org.aopalliance.aop.Advice;
|
||||
|
||||
import org.springframework.aop.BeforeAdvice;
|
||||
import org.springframework.aop.PointcutAdvisor;
|
||||
import org.springframework.aop.framework.AopInfrastructureBean;
|
||||
import org.springframework.security.core.Authentication;
|
||||
|
||||
/**
|
||||
* An advice which can determine if an {@link Authentication} has access to the {@link T}
|
||||
* object. The {@link #getMethodMatcher()} describes when the advice applies for the
|
||||
* method.
|
||||
* An {@link Advice} which can determine if an {@link Authentication} has access to the
|
||||
* {@link T} object. {@link #getPointcut()} describes when the advice applies.
|
||||
*
|
||||
* @param <T> the type of object that the authorization check is being done one.
|
||||
* @author Evgeniy Cheban
|
||||
* @author Josh Cummings
|
||||
* @since 5.5
|
||||
*/
|
||||
public interface AuthorizationMethodBeforeAdvice<T> extends Pointcut {
|
||||
public interface AuthorizationMethodBeforeAdvice<T> extends BeforeAdvice, PointcutAdvisor, AopInfrastructureBean {
|
||||
|
||||
/**
|
||||
* Returns the default {@link ClassFilter}.
|
||||
* @return the {@link ClassFilter#TRUE} to use
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
default ClassFilter getClassFilter() {
|
||||
return ClassFilter.TRUE;
|
||||
default boolean isPerInstance() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
default Advice getAdvice() {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
package org.springframework.security.authorization.method;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.List;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@@ -24,10 +23,11 @@ import org.aopalliance.intercept.MethodInvocation;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.aop.MethodMatcher;
|
||||
import org.springframework.aop.support.StaticMethodMatcher;
|
||||
import org.springframework.aop.Pointcut;
|
||||
import org.springframework.aop.support.ComposablePointcut;
|
||||
import org.springframework.core.log.LogMessage;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* An {@link AuthorizationMethodAfterAdvice} which delegates to specific
|
||||
@@ -35,6 +35,7 @@ import org.springframework.security.core.Authentication;
|
||||
* the {@link MethodInvocation}.
|
||||
*
|
||||
* @author Evgeniy Cheban
|
||||
* @author Josh Cummings
|
||||
* @since 5.5
|
||||
*/
|
||||
public final class DelegatingAuthorizationMethodAfterAdvice
|
||||
@@ -42,18 +43,7 @@ public final class DelegatingAuthorizationMethodAfterAdvice
|
||||
|
||||
private final Log logger = LogFactory.getLog(getClass());
|
||||
|
||||
private final MethodMatcher methodMatcher = new StaticMethodMatcher() {
|
||||
@Override
|
||||
public boolean matches(Method method, Class<?> targetClass) {
|
||||
for (AuthorizationMethodAfterAdvice<MethodAuthorizationContext> delegate : DelegatingAuthorizationMethodAfterAdvice.this.delegates) {
|
||||
MethodMatcher methodMatcher = delegate.getMethodMatcher();
|
||||
if (methodMatcher.matches(method, targetClass)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
private final Pointcut pointcut;
|
||||
|
||||
private final List<AuthorizationMethodAfterAdvice<MethodAuthorizationContext>> delegates;
|
||||
|
||||
@@ -63,12 +53,26 @@ public final class DelegatingAuthorizationMethodAfterAdvice
|
||||
*/
|
||||
public DelegatingAuthorizationMethodAfterAdvice(
|
||||
List<AuthorizationMethodAfterAdvice<MethodAuthorizationContext>> delegates) {
|
||||
Assert.notEmpty(delegates, "delegates cannot be empty");
|
||||
this.delegates = delegates;
|
||||
ComposablePointcut pointcut = null;
|
||||
for (AuthorizationMethodAfterAdvice<?> advice : delegates) {
|
||||
if (pointcut == null) {
|
||||
pointcut = new ComposablePointcut(advice.getPointcut());
|
||||
}
|
||||
else {
|
||||
pointcut.union(advice.getPointcut());
|
||||
}
|
||||
}
|
||||
this.pointcut = pointcut;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public MethodMatcher getMethodMatcher() {
|
||||
return this.methodMatcher;
|
||||
public Pointcut getPointcut() {
|
||||
return this.pointcut;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -16,17 +16,17 @@
|
||||
|
||||
package org.springframework.security.authorization.method;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.List;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.aop.MethodMatcher;
|
||||
import org.springframework.aop.support.StaticMethodMatcher;
|
||||
import org.springframework.aop.Pointcut;
|
||||
import org.springframework.aop.support.ComposablePointcut;
|
||||
import org.springframework.core.log.LogMessage;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* An {@link AuthorizationMethodBeforeAdvice} which delegates to a specific
|
||||
@@ -35,6 +35,7 @@ import org.springframework.security.core.Authentication;
|
||||
* one of the {@link AuthorizationMethodBeforeAdvice}s denied.
|
||||
*
|
||||
* @author Evgeniy Cheban
|
||||
* @author Josh Cummings
|
||||
* @since 5.5
|
||||
*/
|
||||
public final class DelegatingAuthorizationMethodBeforeAdvice
|
||||
@@ -42,18 +43,7 @@ public final class DelegatingAuthorizationMethodBeforeAdvice
|
||||
|
||||
private final Log logger = LogFactory.getLog(getClass());
|
||||
|
||||
private final MethodMatcher methodMatcher = new StaticMethodMatcher() {
|
||||
@Override
|
||||
public boolean matches(Method method, Class<?> targetClass) {
|
||||
for (AuthorizationMethodBeforeAdvice<MethodAuthorizationContext> delegate : DelegatingAuthorizationMethodBeforeAdvice.this.delegates) {
|
||||
MethodMatcher methodMatcher = delegate.getMethodMatcher();
|
||||
if (methodMatcher.matches(method, targetClass)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
private final Pointcut pointcut;
|
||||
|
||||
private final List<AuthorizationMethodBeforeAdvice<MethodAuthorizationContext>> delegates;
|
||||
|
||||
@@ -63,12 +53,26 @@ public final class DelegatingAuthorizationMethodBeforeAdvice
|
||||
*/
|
||||
public DelegatingAuthorizationMethodBeforeAdvice(
|
||||
List<AuthorizationMethodBeforeAdvice<MethodAuthorizationContext>> delegates) {
|
||||
Assert.notEmpty(delegates, "delegates cannot be empty");
|
||||
this.delegates = delegates;
|
||||
ComposablePointcut pointcut = null;
|
||||
for (AuthorizationMethodBeforeAdvice<?> advice : delegates) {
|
||||
if (pointcut == null) {
|
||||
pointcut = new ComposablePointcut(advice.getPointcut());
|
||||
}
|
||||
else {
|
||||
pointcut.union(advice.getPointcut());
|
||||
}
|
||||
}
|
||||
this.pointcut = pointcut;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public MethodMatcher getMethodMatcher() {
|
||||
return this.methodMatcher;
|
||||
public Pointcut getPointcut() {
|
||||
return this.pointcut;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -21,9 +21,8 @@ import java.util.function.Supplier;
|
||||
|
||||
import org.aopalliance.intercept.MethodInvocation;
|
||||
|
||||
import org.springframework.aop.MethodMatcher;
|
||||
import org.springframework.aop.Pointcut;
|
||||
import org.springframework.aop.support.AopUtils;
|
||||
import org.springframework.aop.support.StaticMethodMatcher;
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.expression.EvaluationContext;
|
||||
import org.springframework.expression.Expression;
|
||||
@@ -40,6 +39,7 @@ import org.springframework.util.Assert;
|
||||
* {@link PostFilter} annotation.
|
||||
*
|
||||
* @author Evgeniy Cheban
|
||||
* @author Josh Cummings
|
||||
* @since 5.5
|
||||
*/
|
||||
public final class PostFilterAuthorizationMethodAfterAdvice
|
||||
@@ -47,16 +47,19 @@ public final class PostFilterAuthorizationMethodAfterAdvice
|
||||
|
||||
private final PostFilterExpressionAttributeRegistry registry = new PostFilterExpressionAttributeRegistry();
|
||||
|
||||
private final MethodMatcher methodMatcher = new StaticMethodMatcher() {
|
||||
@Override
|
||||
public boolean matches(Method method, Class<?> targetClass) {
|
||||
return PostFilterAuthorizationMethodAfterAdvice.this.registry.getAttribute(method,
|
||||
targetClass) != ExpressionAttribute.NULL_ATTRIBUTE;
|
||||
}
|
||||
};
|
||||
private final Pointcut pointcut;
|
||||
|
||||
private MethodSecurityExpressionHandler expressionHandler = new DefaultMethodSecurityExpressionHandler();
|
||||
|
||||
/**
|
||||
* Create a {@link PostFilterAuthorizationMethodAfterAdvice} using the provided
|
||||
* parameters
|
||||
* @param pointcut the {@link Pointcut} for when this advice applies
|
||||
*/
|
||||
public PostFilterAuthorizationMethodAfterAdvice(Pointcut pointcut) {
|
||||
this.pointcut = pointcut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link MethodSecurityExpressionHandler}.
|
||||
* @param expressionHandler the {@link MethodSecurityExpressionHandler} to use
|
||||
@@ -66,9 +69,12 @@ public final class PostFilterAuthorizationMethodAfterAdvice
|
||||
this.expressionHandler = expressionHandler;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public MethodMatcher getMethodMatcher() {
|
||||
return this.methodMatcher;
|
||||
public Pointcut getPointcut() {
|
||||
return this.pointcut;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -21,9 +21,8 @@ import java.util.function.Supplier;
|
||||
|
||||
import org.aopalliance.intercept.MethodInvocation;
|
||||
|
||||
import org.springframework.aop.MethodMatcher;
|
||||
import org.springframework.aop.Pointcut;
|
||||
import org.springframework.aop.support.AopUtils;
|
||||
import org.springframework.aop.support.StaticMethodMatcher;
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.expression.EvaluationContext;
|
||||
import org.springframework.expression.Expression;
|
||||
@@ -40,6 +39,7 @@ import org.springframework.util.StringUtils;
|
||||
* evaluating an expression from the {@link PreFilter} annotation.
|
||||
*
|
||||
* @author Evgeniy Cheban
|
||||
* @author Josh Cummings
|
||||
* @since 5.5
|
||||
*/
|
||||
public final class PreFilterAuthorizationMethodBeforeAdvice
|
||||
@@ -47,16 +47,19 @@ public final class PreFilterAuthorizationMethodBeforeAdvice
|
||||
|
||||
private final PreFilterExpressionAttributeRegistry registry = new PreFilterExpressionAttributeRegistry();
|
||||
|
||||
private final MethodMatcher methodMatcher = new StaticMethodMatcher() {
|
||||
@Override
|
||||
public boolean matches(Method method, Class<?> targetClass) {
|
||||
return PreFilterAuthorizationMethodBeforeAdvice.this.registry.getAttribute(method,
|
||||
targetClass) != PreFilterExpressionAttribute.NULL_ATTRIBUTE;
|
||||
}
|
||||
};
|
||||
private final Pointcut pointcut;
|
||||
|
||||
private MethodSecurityExpressionHandler expressionHandler = new DefaultMethodSecurityExpressionHandler();
|
||||
|
||||
/**
|
||||
* Create a {@link PreFilterAuthorizationMethodBeforeAdvice} using the provided
|
||||
* parameters
|
||||
* @param pointcut the {@link Pointcut} for when this advice applies
|
||||
*/
|
||||
public PreFilterAuthorizationMethodBeforeAdvice(Pointcut pointcut) {
|
||||
this.pointcut = pointcut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link MethodSecurityExpressionHandler}.
|
||||
* @param expressionHandler the {@link MethodSecurityExpressionHandler} to use
|
||||
@@ -66,9 +69,12 @@ public final class PreFilterAuthorizationMethodBeforeAdvice
|
||||
this.expressionHandler = expressionHandler;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public MethodMatcher getMethodMatcher() {
|
||||
return this.methodMatcher;
|
||||
public Pointcut getPointcut() {
|
||||
return this.pointcut;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user