diff --git a/config/src/main/java/org/springframework/security/config/annotation/method/configuration/AuthorizationProxyConfiguration.java b/config/src/main/java/org/springframework/security/config/annotation/method/configuration/AuthorizationProxyConfiguration.java index 6868703806..9ef918df58 100644 --- a/config/src/main/java/org/springframework/security/config/annotation/method/configuration/AuthorizationProxyConfiguration.java +++ b/config/src/main/java/org/springframework/security/config/annotation/method/configuration/AuthorizationProxyConfiguration.java @@ -17,6 +17,7 @@ package org.springframework.security.config.annotation.method.configuration; import java.util.ArrayList; +import java.util.List; import org.aopalliance.intercept.MethodInterceptor; @@ -40,21 +41,19 @@ final class AuthorizationProxyConfiguration implements AopInfrastructureBean { @Bean @Role(BeanDefinition.ROLE_INFRASTRUCTURE) static AuthorizationAdvisorProxyFactory authorizationProxyFactory( + ObjectProvider authorizationAdvisors, ObjectProvider> customizers) { - AuthorizationAdvisorProxyFactory factory = new AuthorizationAdvisorProxyFactory(new ArrayList<>()); + List advisors = new ArrayList<>(); + authorizationAdvisors.forEach(advisors::add); + AuthorizationAdvisorProxyFactory factory = new AuthorizationAdvisorProxyFactory(advisors); customizers.forEach((c) -> c.customize(factory)); return factory; } @Bean @Role(BeanDefinition.ROLE_INFRASTRUCTURE) - static MethodInterceptor authorizeReturnObjectMethodInterceptor(ObjectProvider provider, - AuthorizationAdvisorProxyFactory authorizationProxyFactory) { - provider.forEach(authorizationProxyFactory::addAdvisor); - AuthorizeReturnObjectMethodInterceptor interceptor = new AuthorizeReturnObjectMethodInterceptor( - authorizationProxyFactory); - authorizationProxyFactory.addAdvisor(interceptor); - return interceptor; + static MethodInterceptor authorizeReturnObjectMethodInterceptor() { + return new AuthorizeReturnObjectMethodInterceptor(); } @Bean diff --git a/core/src/main/java/org/springframework/security/authorization/method/AuthorizationAdvisorProxyFactory.java b/core/src/main/java/org/springframework/security/authorization/method/AuthorizationAdvisorProxyFactory.java index 3b18466743..dd4abb3754 100644 --- a/core/src/main/java/org/springframework/security/authorization/method/AuthorizationAdvisorProxyFactory.java +++ b/core/src/main/java/org/springframework/security/authorization/method/AuthorizationAdvisorProxyFactory.java @@ -100,16 +100,16 @@ public final class AuthorizationAdvisorProxyFactory implements AuthorizationProx /** * Construct an {@link AuthorizationAdvisorProxyFactory} with the provided advisors. - * - *

- * The list may be empty, in the case where advisors are added later using - * {@link #addAdvisor}. * @param advisors the advisors to use * @since 6.4 */ public AuthorizationAdvisorProxyFactory(List advisors) { this.advisors = new ArrayList<>(advisors); - AnnotationAwareOrderComparator.sort(this.advisors); + for (AuthorizationAdvisor advisor : this.advisors) { + if (advisor instanceof AuthorizeReturnObjectMethodInterceptor interceptor) { + interceptor.setAuthorizationProxyFactory(this); + } + } } /** @@ -124,8 +124,8 @@ public final class AuthorizationAdvisorProxyFactory implements AuthorizationProx advisors.add(AuthorizationManagerAfterMethodInterceptor.postAuthorize()); advisors.add(new PreFilterAuthorizationMethodInterceptor()); advisors.add(new PostFilterAuthorizationMethodInterceptor()); + advisors.add(new AuthorizeReturnObjectMethodInterceptor()); AuthorizationAdvisorProxyFactory proxyFactory = new AuthorizationAdvisorProxyFactory(advisors); - proxyFactory.addAdvisor(new AuthorizeReturnObjectMethodInterceptor(proxyFactory)); AnnotationAwareOrderComparator.sort(proxyFactory.advisors); return proxyFactory; } @@ -142,8 +142,8 @@ public final class AuthorizationAdvisorProxyFactory implements AuthorizationProx advisors.add(AuthorizationManagerAfterReactiveMethodInterceptor.postAuthorize()); advisors.add(new PreFilterAuthorizationReactiveMethodInterceptor()); advisors.add(new PostFilterAuthorizationReactiveMethodInterceptor()); + advisors.add(new AuthorizeReturnObjectMethodInterceptor()); AuthorizationAdvisorProxyFactory proxyFactory = new AuthorizationAdvisorProxyFactory(advisors); - proxyFactory.addAdvisor(new AuthorizeReturnObjectMethodInterceptor(proxyFactory)); AnnotationAwareOrderComparator.sort(proxyFactory.advisors); return proxyFactory; } @@ -230,7 +230,9 @@ public final class AuthorizationAdvisorProxyFactory implements AuthorizationProx * them. * @param advisor * @since 6.4 + * @deprecated please provide all advisors in the constructor */ + @Deprecated public void addAdvisor(AuthorizationAdvisor advisor) { this.advisors.add(advisor); } diff --git a/core/src/main/java/org/springframework/security/authorization/method/AuthorizeReturnObjectMethodInterceptor.java b/core/src/main/java/org/springframework/security/authorization/method/AuthorizeReturnObjectMethodInterceptor.java index 5308b8d251..5a69fa11f1 100644 --- a/core/src/main/java/org/springframework/security/authorization/method/AuthorizeReturnObjectMethodInterceptor.java +++ b/core/src/main/java/org/springframework/security/authorization/method/AuthorizeReturnObjectMethodInterceptor.java @@ -39,7 +39,7 @@ import org.springframework.util.ClassUtils; */ public final class AuthorizeReturnObjectMethodInterceptor implements AuthorizationAdvisor { - private final AuthorizationProxyFactory authorizationProxyFactory; + private AuthorizationProxyFactory authorizationProxyFactory; private Pointcut pointcut = Pointcuts.intersection( new MethodReturnTypePointcut(Predicate.not(ClassUtils::isVoidType)), @@ -47,6 +47,19 @@ public final class AuthorizeReturnObjectMethodInterceptor implements Authorizati private int order = AuthorizationInterceptorsOrder.SECURE_RESULT.getOrder(); + /** + * Construct the interceptor + * + *

+ * Using this constructor requires you to specify + * {@link #setAuthorizationProxyFactory} + *

+ * @since 6.5 + */ + public AuthorizeReturnObjectMethodInterceptor() { + + } + public AuthorizeReturnObjectMethodInterceptor(AuthorizationProxyFactory authorizationProxyFactory) { Assert.notNull(authorizationProxyFactory, "authorizationProxyFactory cannot be null"); this.authorizationProxyFactory = authorizationProxyFactory; @@ -58,9 +71,20 @@ public final class AuthorizeReturnObjectMethodInterceptor implements Authorizati if (result == null) { return null; } + Assert.notNull(this.authorizationProxyFactory, "authorizationProxyFactory cannot be null"); return this.authorizationProxyFactory.proxy(result); } + /** + * Use this {@link AuthorizationProxyFactory} + * @param authorizationProxyFactory the proxy factory to use + * @since 6.5 + */ + public void setAuthorizationProxyFactory(AuthorizationProxyFactory authorizationProxyFactory) { + Assert.notNull(authorizationProxyFactory, "authorizationProxyFactory cannot be null"); + this.authorizationProxyFactory = authorizationProxyFactory; + } + @Override public int getOrder() { return this.order;