16
16
17
17
package org .springframework .security .config .annotation .method .configuration ;
18
18
19
+ import java .util .function .Consumer ;
20
+ import java .util .function .Supplier ;
21
+
19
22
import io .micrometer .observation .ObservationRegistry ;
23
+ import org .aopalliance .aop .Advice ;
24
+ import org .aopalliance .intercept .MethodInterceptor ;
20
25
import org .aopalliance .intercept .MethodInvocation ;
26
+ import org .jetbrains .annotations .NotNull ;
27
+ import org .jetbrains .annotations .Nullable ;
21
28
29
+ import org .springframework .aop .Pointcut ;
30
+ import org .springframework .aop .framework .AopInfrastructureBean ;
22
31
import org .springframework .beans .factory .ObjectProvider ;
23
32
import org .springframework .beans .factory .annotation .Autowired ;
24
33
import org .springframework .beans .factory .config .BeanDefinition ;
29
38
import org .springframework .security .access .expression .method .MethodSecurityExpressionHandler ;
30
39
import org .springframework .security .authentication .ReactiveAuthenticationManager ;
31
40
import org .springframework .security .authorization .ReactiveAuthorizationManager ;
41
+ import org .springframework .security .authorization .method .AuthorizationAdvisor ;
32
42
import org .springframework .security .authorization .method .AuthorizationManagerAfterReactiveMethodInterceptor ;
33
43
import org .springframework .security .authorization .method .AuthorizationManagerBeforeReactiveMethodInterceptor ;
34
44
import org .springframework .security .authorization .method .MethodInvocationResult ;
38
48
import org .springframework .security .authorization .method .PreFilterAuthorizationReactiveMethodInterceptor ;
39
49
import org .springframework .security .authorization .method .PrePostTemplateDefaults ;
40
50
import org .springframework .security .config .core .GrantedAuthorityDefaults ;
51
+ import org .springframework .util .function .SingletonSupplier ;
41
52
42
53
/**
43
54
* Configuration for a {@link ReactiveAuthenticationManager} based Method Security.
46
57
* @since 5.8
47
58
*/
48
59
@ Configuration (proxyBeanMethods = false )
49
- final class ReactiveAuthorizationManagerMethodSecurityConfiguration {
60
+ final class ReactiveAuthorizationManagerMethodSecurityConfiguration implements AopInfrastructureBean {
50
61
51
62
@ Bean
52
63
@ Role (BeanDefinition .ROLE_INFRASTRUCTURE )
53
- static PreFilterAuthorizationReactiveMethodInterceptor preFilterInterceptor (
54
- MethodSecurityExpressionHandler expressionHandler ,
64
+ static MethodInterceptor preFilterAuthorizationMethodInterceptor (MethodSecurityExpressionHandler expressionHandler ,
55
65
ObjectProvider <PrePostTemplateDefaults > defaultsObjectProvider ) {
56
66
PreFilterAuthorizationReactiveMethodInterceptor interceptor = new PreFilterAuthorizationReactiveMethodInterceptor (
57
67
expressionHandler );
58
- defaultsObjectProvider . ifAvailable (interceptor :: setTemplateDefaults );
59
- return interceptor ;
68
+ return new DeferringMethodInterceptor <> (interceptor ,
69
+ ( i ) -> defaultsObjectProvider . ifAvailable ( i :: setTemplateDefaults )) ;
60
70
}
61
71
62
72
@ Bean
63
73
@ Role (BeanDefinition .ROLE_INFRASTRUCTURE )
64
- static AuthorizationManagerBeforeReactiveMethodInterceptor preAuthorizeInterceptor (
74
+ static MethodInterceptor preAuthorizeAuthorizationMethodInterceptor (
65
75
MethodSecurityExpressionHandler expressionHandler ,
66
76
ObjectProvider <PrePostTemplateDefaults > defaultsObjectProvider ,
67
77
ObjectProvider <ObservationRegistry > registryProvider ) {
68
78
PreAuthorizeReactiveAuthorizationManager manager = new PreAuthorizeReactiveAuthorizationManager (
69
79
expressionHandler );
70
- defaultsObjectProvider .ifAvailable (manager ::setTemplateDefaults );
71
80
ReactiveAuthorizationManager <MethodInvocation > authorizationManager = manager (manager , registryProvider );
72
- return AuthorizationManagerBeforeReactiveMethodInterceptor .preAuthorize (authorizationManager );
81
+ AuthorizationAdvisor interceptor = AuthorizationManagerBeforeReactiveMethodInterceptor
82
+ .preAuthorize (authorizationManager );
83
+ return new DeferringMethodInterceptor <>(interceptor ,
84
+ (i ) -> defaultsObjectProvider .ifAvailable (manager ::setTemplateDefaults ));
73
85
}
74
86
75
87
@ Bean
76
88
@ Role (BeanDefinition .ROLE_INFRASTRUCTURE )
77
- static PostFilterAuthorizationReactiveMethodInterceptor postFilterInterceptor (
78
- MethodSecurityExpressionHandler expressionHandler ,
89
+ static MethodInterceptor postFilterAuthorizationMethodInterceptor (MethodSecurityExpressionHandler expressionHandler ,
79
90
ObjectProvider <PrePostTemplateDefaults > defaultsObjectProvider ) {
80
91
PostFilterAuthorizationReactiveMethodInterceptor interceptor = new PostFilterAuthorizationReactiveMethodInterceptor (
81
92
expressionHandler );
82
- defaultsObjectProvider . ifAvailable (interceptor :: setTemplateDefaults );
83
- return interceptor ;
93
+ return new DeferringMethodInterceptor <> (interceptor ,
94
+ ( i ) -> defaultsObjectProvider . ifAvailable ( i :: setTemplateDefaults )) ;
84
95
}
85
96
86
97
@ Bean
87
98
@ Role (BeanDefinition .ROLE_INFRASTRUCTURE )
88
- static AuthorizationManagerAfterReactiveMethodInterceptor postAuthorizeInterceptor (
99
+ static MethodInterceptor postAuthorizeAuthorizationMethodInterceptor (
89
100
MethodSecurityExpressionHandler expressionHandler ,
90
101
ObjectProvider <PrePostTemplateDefaults > defaultsObjectProvider ,
91
102
ObjectProvider <ObservationRegistry > registryProvider ) {
92
103
PostAuthorizeReactiveAuthorizationManager manager = new PostAuthorizeReactiveAuthorizationManager (
93
104
expressionHandler );
94
105
ReactiveAuthorizationManager <MethodInvocationResult > authorizationManager = manager (manager , registryProvider );
95
- defaultsObjectProvider .ifAvailable (manager ::setTemplateDefaults );
96
- return AuthorizationManagerAfterReactiveMethodInterceptor .postAuthorize (authorizationManager );
106
+ AuthorizationAdvisor interceptor = AuthorizationManagerAfterReactiveMethodInterceptor
107
+ .postAuthorize (authorizationManager );
108
+ return new DeferringMethodInterceptor <>(interceptor ,
109
+ (i ) -> defaultsObjectProvider .ifAvailable (manager ::setTemplateDefaults ));
97
110
}
98
111
99
112
@ Bean
@@ -112,4 +125,50 @@ static <T> ReactiveAuthorizationManager<T> manager(ReactiveAuthorizationManager<
112
125
return new DeferringObservationReactiveAuthorizationManager <>(registryProvider , delegate );
113
126
}
114
127
128
+ private static final class DeferringMethodInterceptor <M extends AuthorizationAdvisor >
129
+ implements AuthorizationAdvisor {
130
+
131
+ private final Pointcut pointcut ;
132
+
133
+ private final int order ;
134
+
135
+ private final Supplier <M > delegate ;
136
+
137
+ DeferringMethodInterceptor (M delegate , Consumer <M > supplier ) {
138
+ this .pointcut = delegate .getPointcut ();
139
+ this .order = delegate .getOrder ();
140
+ this .delegate = SingletonSupplier .of (() -> {
141
+ supplier .accept (delegate );
142
+ return delegate ;
143
+ });
144
+ }
145
+
146
+ @ Nullable
147
+ @ Override
148
+ public Object invoke (@ NotNull MethodInvocation invocation ) throws Throwable {
149
+ return this .delegate .get ().invoke (invocation );
150
+ }
151
+
152
+ @ Override
153
+ public Pointcut getPointcut () {
154
+ return this .pointcut ;
155
+ }
156
+
157
+ @ Override
158
+ public Advice getAdvice () {
159
+ return this ;
160
+ }
161
+
162
+ @ Override
163
+ public int getOrder () {
164
+ return this .order ;
165
+ }
166
+
167
+ @ Override
168
+ public boolean isPerInstance () {
169
+ return true ;
170
+ }
171
+
172
+ }
173
+
115
174
}
0 commit comments