Skip to content

Commit 2bb3787

Browse files
committed
Use addAdvisors in Reactive Proxy Configuration
Issue gh-15497
1 parent 3ee973d commit 2bb3787

File tree

3 files changed

+86
-162
lines changed

3 files changed

+86
-162
lines changed

config/src/main/java/org/springframework/security/config/annotation/method/configuration/ReactiveAuthorizationManagerMethodSecurityConfiguration.java

Lines changed: 85 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -16,101 +16,139 @@
1616

1717
package org.springframework.security.config.annotation.method.configuration;
1818

19-
import java.util.function.Consumer;
20-
import java.util.function.Supplier;
21-
2219
import io.micrometer.observation.ObservationRegistry;
23-
import org.aopalliance.aop.Advice;
2420
import org.aopalliance.intercept.MethodInterceptor;
25-
import org.aopalliance.intercept.MethodInvocation;
26-
import org.jetbrains.annotations.NotNull;
27-
import org.jetbrains.annotations.Nullable;
2821

2922
import org.springframework.aop.Pointcut;
3023
import org.springframework.aop.framework.AopInfrastructureBean;
24+
import org.springframework.beans.BeansException;
3125
import org.springframework.beans.factory.ObjectProvider;
3226
import org.springframework.beans.factory.annotation.Autowired;
3327
import org.springframework.beans.factory.config.BeanDefinition;
3428
import org.springframework.context.ApplicationContext;
29+
import org.springframework.context.ApplicationContextAware;
3530
import org.springframework.context.annotation.Bean;
3631
import org.springframework.context.annotation.Configuration;
3732
import org.springframework.context.annotation.Fallback;
3833
import org.springframework.context.annotation.Role;
3934
import org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler;
4035
import org.springframework.security.access.expression.method.MethodSecurityExpressionHandler;
4136
import org.springframework.security.authentication.ReactiveAuthenticationManager;
42-
import org.springframework.security.authorization.ReactiveAuthorizationManager;
43-
import org.springframework.security.authorization.method.AuthorizationAdvisor;
37+
import org.springframework.security.authorization.ObservationReactiveAuthorizationManager;
4438
import org.springframework.security.authorization.method.AuthorizationManagerAfterReactiveMethodInterceptor;
4539
import org.springframework.security.authorization.method.AuthorizationManagerBeforeReactiveMethodInterceptor;
46-
import org.springframework.security.authorization.method.MethodInvocationResult;
4740
import org.springframework.security.authorization.method.PostAuthorizeReactiveAuthorizationManager;
4841
import org.springframework.security.authorization.method.PostFilterAuthorizationReactiveMethodInterceptor;
4942
import org.springframework.security.authorization.method.PreAuthorizeReactiveAuthorizationManager;
5043
import org.springframework.security.authorization.method.PreFilterAuthorizationReactiveMethodInterceptor;
5144
import org.springframework.security.authorization.method.PrePostTemplateDefaults;
5245
import org.springframework.security.config.core.GrantedAuthorityDefaults;
53-
import org.springframework.util.function.SingletonSupplier;
5446

5547
/**
5648
* Configuration for a {@link ReactiveAuthenticationManager} based Method Security.
5749
*
5850
* @author Evgeniy Cheban
5951
* @since 5.8
6052
*/
61-
@Configuration(proxyBeanMethods = false)
62-
final class ReactiveAuthorizationManagerMethodSecurityConfiguration implements AopInfrastructureBean {
53+
@Configuration(value = "_reactiveMethodSecurityConfiguration", proxyBeanMethods = false)
54+
final class ReactiveAuthorizationManagerMethodSecurityConfiguration
55+
implements AopInfrastructureBean, ApplicationContextAware {
56+
57+
private static final Pointcut preFilterPointcut = new PreFilterAuthorizationReactiveMethodInterceptor()
58+
.getPointcut();
59+
60+
private static final Pointcut preAuthorizePointcut = AuthorizationManagerBeforeReactiveMethodInterceptor
61+
.preAuthorize()
62+
.getPointcut();
63+
64+
private static final Pointcut postAuthorizePointcut = AuthorizationManagerAfterReactiveMethodInterceptor
65+
.postAuthorize()
66+
.getPointcut();
67+
68+
private static final Pointcut postFilterPointcut = new PostFilterAuthorizationReactiveMethodInterceptor()
69+
.getPointcut();
70+
71+
private PreFilterAuthorizationReactiveMethodInterceptor preFilterMethodInterceptor = new PreFilterAuthorizationReactiveMethodInterceptor();
72+
73+
private PreAuthorizeReactiveAuthorizationManager preAuthorizeAuthorizationManager = new PreAuthorizeReactiveAuthorizationManager();
74+
75+
private PostAuthorizeReactiveAuthorizationManager postAuthorizeAuthorizationManager = new PostAuthorizeReactiveAuthorizationManager();
76+
77+
private PostFilterAuthorizationReactiveMethodInterceptor postFilterMethodInterceptor = new PostFilterAuthorizationReactiveMethodInterceptor();
78+
79+
private AuthorizationManagerBeforeReactiveMethodInterceptor preAuthorizeMethodInterceptor;
80+
81+
private AuthorizationManagerAfterReactiveMethodInterceptor postAuthorizeMethodInterceptor;
82+
83+
@Autowired(required = false)
84+
ReactiveAuthorizationManagerMethodSecurityConfiguration(MethodSecurityExpressionHandler expressionHandler) {
85+
if (expressionHandler != null) {
86+
this.preFilterMethodInterceptor = new PreFilterAuthorizationReactiveMethodInterceptor(expressionHandler);
87+
this.preAuthorizeAuthorizationManager = new PreAuthorizeReactiveAuthorizationManager(expressionHandler);
88+
this.postFilterMethodInterceptor = new PostFilterAuthorizationReactiveMethodInterceptor(expressionHandler);
89+
this.postAuthorizeAuthorizationManager = new PostAuthorizeReactiveAuthorizationManager(expressionHandler);
90+
}
91+
this.preAuthorizeMethodInterceptor = AuthorizationManagerBeforeReactiveMethodInterceptor
92+
.preAuthorize(this.preAuthorizeAuthorizationManager);
93+
this.postAuthorizeMethodInterceptor = AuthorizationManagerAfterReactiveMethodInterceptor
94+
.postAuthorize(this.postAuthorizeAuthorizationManager);
95+
}
96+
97+
@Override
98+
public void setApplicationContext(ApplicationContext context) throws BeansException {
99+
this.preAuthorizeAuthorizationManager.setApplicationContext(context);
100+
this.postAuthorizeAuthorizationManager.setApplicationContext(context);
101+
}
102+
103+
@Autowired(required = false)
104+
void setTemplateDefaults(PrePostTemplateDefaults templateDefaults) {
105+
this.preFilterMethodInterceptor.setTemplateDefaults(templateDefaults);
106+
this.preAuthorizeAuthorizationManager.setTemplateDefaults(templateDefaults);
107+
this.postAuthorizeAuthorizationManager.setTemplateDefaults(templateDefaults);
108+
this.postFilterMethodInterceptor.setTemplateDefaults(templateDefaults);
109+
}
110+
111+
@Autowired(required = false)
112+
void setObservationRegistry(ObservationRegistry registry) {
113+
if (registry.isNoop()) {
114+
return;
115+
}
116+
this.preAuthorizeMethodInterceptor = AuthorizationManagerBeforeReactiveMethodInterceptor.preAuthorize(
117+
new ObservationReactiveAuthorizationManager<>(registry, this.preAuthorizeAuthorizationManager));
118+
this.postAuthorizeMethodInterceptor = AuthorizationManagerAfterReactiveMethodInterceptor.postAuthorize(
119+
new ObservationReactiveAuthorizationManager<>(registry, this.postAuthorizeAuthorizationManager));
120+
}
63121

64122
@Bean
65123
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
66-
static MethodInterceptor preFilterAuthorizationMethodInterceptor(MethodSecurityExpressionHandler expressionHandler,
67-
ObjectProvider<PrePostTemplateDefaults> defaultsObjectProvider) {
68-
PreFilterAuthorizationReactiveMethodInterceptor interceptor = new PreFilterAuthorizationReactiveMethodInterceptor(
69-
expressionHandler);
70-
return new DeferringMethodInterceptor<>(interceptor,
71-
(i) -> defaultsObjectProvider.ifAvailable(i::setTemplateDefaults));
124+
static MethodInterceptor preFilterAuthorizationMethodInterceptor(
125+
ObjectProvider<ReactiveAuthorizationManagerMethodSecurityConfiguration> _reactiveMethodSecurityConfiguration) {
126+
return new DeferringMethodInterceptor<>(preFilterPointcut,
127+
() -> _reactiveMethodSecurityConfiguration.getObject().preFilterMethodInterceptor);
72128
}
73129

74130
@Bean
75131
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
76132
static MethodInterceptor preAuthorizeAuthorizationMethodInterceptor(
77-
MethodSecurityExpressionHandler expressionHandler,
78-
ObjectProvider<PrePostTemplateDefaults> defaultsObjectProvider,
79-
ObjectProvider<ObservationRegistry> registryProvider, ApplicationContext context) {
80-
PreAuthorizeReactiveAuthorizationManager manager = new PreAuthorizeReactiveAuthorizationManager(
81-
expressionHandler);
82-
manager.setApplicationContext(context);
83-
ReactiveAuthorizationManager<MethodInvocation> authorizationManager = manager(manager, registryProvider);
84-
AuthorizationAdvisor interceptor = AuthorizationManagerBeforeReactiveMethodInterceptor
85-
.preAuthorize(authorizationManager);
86-
return new DeferringMethodInterceptor<>(interceptor,
87-
(i) -> defaultsObjectProvider.ifAvailable(manager::setTemplateDefaults));
133+
ObjectProvider<ReactiveAuthorizationManagerMethodSecurityConfiguration> _reactiveMethodSecurityConfiguration) {
134+
return new DeferringMethodInterceptor<>(preAuthorizePointcut,
135+
() -> _reactiveMethodSecurityConfiguration.getObject().preAuthorizeMethodInterceptor);
88136
}
89137

90138
@Bean
91139
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
92-
static MethodInterceptor postFilterAuthorizationMethodInterceptor(MethodSecurityExpressionHandler expressionHandler,
93-
ObjectProvider<PrePostTemplateDefaults> defaultsObjectProvider) {
94-
PostFilterAuthorizationReactiveMethodInterceptor interceptor = new PostFilterAuthorizationReactiveMethodInterceptor(
95-
expressionHandler);
96-
return new DeferringMethodInterceptor<>(interceptor,
97-
(i) -> defaultsObjectProvider.ifAvailable(i::setTemplateDefaults));
140+
static MethodInterceptor postFilterAuthorizationMethodInterceptor(
141+
ObjectProvider<ReactiveAuthorizationManagerMethodSecurityConfiguration> _reactiveMethodSecurityConfiguration) {
142+
return new DeferringMethodInterceptor<>(postFilterPointcut,
143+
() -> _reactiveMethodSecurityConfiguration.getObject().postFilterMethodInterceptor);
98144
}
99145

100146
@Bean
101147
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
102148
static MethodInterceptor postAuthorizeAuthorizationMethodInterceptor(
103-
MethodSecurityExpressionHandler expressionHandler,
104-
ObjectProvider<PrePostTemplateDefaults> defaultsObjectProvider,
105-
ObjectProvider<ObservationRegistry> registryProvider, ApplicationContext context) {
106-
PostAuthorizeReactiveAuthorizationManager manager = new PostAuthorizeReactiveAuthorizationManager(
107-
expressionHandler);
108-
manager.setApplicationContext(context);
109-
ReactiveAuthorizationManager<MethodInvocationResult> authorizationManager = manager(manager, registryProvider);
110-
AuthorizationAdvisor interceptor = AuthorizationManagerAfterReactiveMethodInterceptor
111-
.postAuthorize(authorizationManager);
112-
return new DeferringMethodInterceptor<>(interceptor,
113-
(i) -> defaultsObjectProvider.ifAvailable(manager::setTemplateDefaults));
149+
ObjectProvider<ReactiveAuthorizationManagerMethodSecurityConfiguration> _reactiveMethodSecurityConfiguration) {
150+
return new DeferringMethodInterceptor<>(postAuthorizePointcut,
151+
() -> _reactiveMethodSecurityConfiguration.getObject().postAuthorizeMethodInterceptor);
114152
}
115153

116154
@Bean
@@ -125,55 +163,4 @@ static DefaultMethodSecurityExpressionHandler methodSecurityExpressionHandler(
125163
return handler;
126164
}
127165

128-
static <T> ReactiveAuthorizationManager<T> manager(ReactiveAuthorizationManager<T> delegate,
129-
ObjectProvider<ObservationRegistry> registryProvider) {
130-
return new DeferringObservationReactiveAuthorizationManager<>(registryProvider, delegate);
131-
}
132-
133-
private static final class DeferringMethodInterceptor<M extends AuthorizationAdvisor>
134-
implements AuthorizationAdvisor {
135-
136-
private final Pointcut pointcut;
137-
138-
private final int order;
139-
140-
private final Supplier<M> delegate;
141-
142-
DeferringMethodInterceptor(M delegate, Consumer<M> supplier) {
143-
this.pointcut = delegate.getPointcut();
144-
this.order = delegate.getOrder();
145-
this.delegate = SingletonSupplier.of(() -> {
146-
supplier.accept(delegate);
147-
return delegate;
148-
});
149-
}
150-
151-
@Nullable
152-
@Override
153-
public Object invoke(@NotNull MethodInvocation invocation) throws Throwable {
154-
return this.delegate.get().invoke(invocation);
155-
}
156-
157-
@Override
158-
public Pointcut getPointcut() {
159-
return this.pointcut;
160-
}
161-
162-
@Override
163-
public Advice getAdvice() {
164-
return this;
165-
}
166-
167-
@Override
168-
public int getOrder() {
169-
return this.order;
170-
}
171-
172-
@Override
173-
public boolean isPerInstance() {
174-
return true;
175-
}
176-
177-
}
178-
179166
}

config/src/main/java/org/springframework/security/config/annotation/method/configuration/ReactiveAuthorizationProxyConfiguration.java

Lines changed: 0 additions & 63 deletions
This file was deleted.

config/src/main/java/org/springframework/security/config/annotation/method/configuration/ReactiveMethodSecuritySelector.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ public String[] selectImports(AnnotationMetadata importMetadata) {
5151
else {
5252
imports.add(ReactiveMethodSecurityConfiguration.class.getName());
5353
}
54-
imports.add(ReactiveAuthorizationProxyConfiguration.class.getName());
54+
imports.add(AuthorizationProxyConfiguration.class.getName());
5555
return imports.toArray(new String[0]);
5656
}
5757

0 commit comments

Comments
 (0)