16
16
17
17
package org .springframework .security .config .annotation .method .configuration ;
18
18
19
+ import java .util .function .Supplier ;
20
+
19
21
import io .micrometer .observation .ObservationRegistry ;
20
22
import org .aopalliance .intercept .MethodInterceptor ;
23
+ import org .aopalliance .intercept .MethodInvocation ;
21
24
22
25
import org .springframework .beans .factory .ObjectProvider ;
23
26
import org .springframework .beans .factory .config .BeanDefinition ;
24
27
import org .springframework .context .ApplicationContext ;
25
28
import org .springframework .context .annotation .Bean ;
26
29
import org .springframework .context .annotation .Configuration ;
27
30
import org .springframework .context .annotation .Role ;
31
+ import org .springframework .expression .EvaluationContext ;
32
+ import org .springframework .expression .Expression ;
33
+ import org .springframework .expression .ExpressionParser ;
28
34
import org .springframework .security .access .expression .method .DefaultMethodSecurityExpressionHandler ;
29
35
import org .springframework .security .access .expression .method .MethodSecurityExpressionHandler ;
30
36
import org .springframework .security .authorization .AuthorizationEventPublisher ;
36
42
import org .springframework .security .authorization .method .PreAuthorizeAuthorizationManager ;
37
43
import org .springframework .security .authorization .method .PreFilterAuthorizationMethodInterceptor ;
38
44
import org .springframework .security .config .core .GrantedAuthorityDefaults ;
45
+ import org .springframework .security .core .Authentication ;
39
46
import org .springframework .security .core .context .SecurityContextHolderStrategy ;
47
+ import org .springframework .util .function .SingletonSupplier ;
40
48
41
49
/**
42
50
* Base {@link Configuration} for enabling Spring Security Method Security.
@@ -59,7 +67,7 @@ static MethodInterceptor preFilterAuthorizationMethodInterceptor(
59
67
PreFilterAuthorizationMethodInterceptor preFilter = new PreFilterAuthorizationMethodInterceptor ();
60
68
strategyProvider .ifAvailable (preFilter ::setSecurityContextHolderStrategy );
61
69
preFilter .setExpressionHandler (
62
- expressionHandlerProvider . getIfAvailable (() -> defaultExpressionHandler ( defaultsProvider , context ) ));
70
+ new DeferringMethodSecurityExpressionHandler ( expressionHandlerProvider , defaultsProvider , context ));
63
71
return preFilter ;
64
72
}
65
73
@@ -73,7 +81,7 @@ static MethodInterceptor preAuthorizeAuthorizationMethodInterceptor(
73
81
ObjectProvider <ObservationRegistry > registryProvider , ApplicationContext context ) {
74
82
PreAuthorizeAuthorizationManager manager = new PreAuthorizeAuthorizationManager ();
75
83
manager .setExpressionHandler (
76
- expressionHandlerProvider . getIfAvailable (() -> defaultExpressionHandler ( defaultsProvider , context ) ));
84
+ new DeferringMethodSecurityExpressionHandler ( expressionHandlerProvider , defaultsProvider , context ));
77
85
AuthorizationManagerBeforeMethodInterceptor preAuthorize = AuthorizationManagerBeforeMethodInterceptor
78
86
.preAuthorize (manager (manager , registryProvider ));
79
87
strategyProvider .ifAvailable (preAuthorize ::setSecurityContextHolderStrategy );
@@ -91,7 +99,7 @@ static MethodInterceptor postAuthorizeAuthorizationMethodInterceptor(
91
99
ObjectProvider <ObservationRegistry > registryProvider , ApplicationContext context ) {
92
100
PostAuthorizeAuthorizationManager manager = new PostAuthorizeAuthorizationManager ();
93
101
manager .setExpressionHandler (
94
- expressionHandlerProvider . getIfAvailable (() -> defaultExpressionHandler ( defaultsProvider , context ) ));
102
+ new DeferringMethodSecurityExpressionHandler ( expressionHandlerProvider , defaultsProvider , context ));
95
103
AuthorizationManagerAfterMethodInterceptor postAuthorize = AuthorizationManagerAfterMethodInterceptor
96
104
.postAuthorize (manager (manager , registryProvider ));
97
105
strategyProvider .ifAvailable (postAuthorize ::setSecurityContextHolderStrategy );
@@ -108,7 +116,7 @@ static MethodInterceptor postFilterAuthorizationMethodInterceptor(
108
116
PostFilterAuthorizationMethodInterceptor postFilter = new PostFilterAuthorizationMethodInterceptor ();
109
117
strategyProvider .ifAvailable (postFilter ::setSecurityContextHolderStrategy );
110
118
postFilter .setExpressionHandler (
111
- expressionHandlerProvider . getIfAvailable (() -> defaultExpressionHandler ( defaultsProvider , context ) ));
119
+ new DeferringMethodSecurityExpressionHandler ( expressionHandlerProvider , defaultsProvider , context ));
112
120
return postFilter ;
113
121
}
114
122
@@ -125,4 +133,43 @@ static <T> AuthorizationManager<T> manager(AuthorizationManager<T> delegate,
125
133
return new DeferringObservationAuthorizationManager <>(registryProvider , delegate );
126
134
}
127
135
136
+ private static final class DeferringMethodSecurityExpressionHandler implements MethodSecurityExpressionHandler {
137
+
138
+ private final Supplier <MethodSecurityExpressionHandler > expressionHandler ;
139
+
140
+ private DeferringMethodSecurityExpressionHandler (
141
+ ObjectProvider <MethodSecurityExpressionHandler > expressionHandlerProvider ,
142
+ ObjectProvider <GrantedAuthorityDefaults > defaultsProvider , ApplicationContext applicationContext ) {
143
+ this .expressionHandler = SingletonSupplier .of (() -> expressionHandlerProvider
144
+ .getIfAvailable (() -> defaultExpressionHandler (defaultsProvider , applicationContext )));
145
+ }
146
+
147
+ @ Override
148
+ public ExpressionParser getExpressionParser () {
149
+ return this .expressionHandler .get ().getExpressionParser ();
150
+ }
151
+
152
+ @ Override
153
+ public EvaluationContext createEvaluationContext (Authentication authentication , MethodInvocation invocation ) {
154
+ return this .expressionHandler .get ().createEvaluationContext (authentication , invocation );
155
+ }
156
+
157
+ @ Override
158
+ public EvaluationContext createEvaluationContext (Supplier <Authentication > authentication ,
159
+ MethodInvocation invocation ) {
160
+ return this .expressionHandler .get ().createEvaluationContext (authentication , invocation );
161
+ }
162
+
163
+ @ Override
164
+ public Object filter (Object filterTarget , Expression filterExpression , EvaluationContext ctx ) {
165
+ return this .expressionHandler .get ().filter (filterTarget , filterExpression , ctx );
166
+ }
167
+
168
+ @ Override
169
+ public void setReturnObject (Object returnObject , EvaluationContext ctx ) {
170
+ this .expressionHandler .get ().setReturnObject (returnObject , ctx );
171
+ }
172
+
173
+ }
174
+
128
175
}
0 commit comments