1616
1717package org .springframework .security .config .annotation .method .configuration ;
1818
19+ import java .util .function .Supplier ;
20+
1921import io .micrometer .observation .ObservationRegistry ;
2022import org .aopalliance .intercept .MethodInterceptor ;
23+ import org .aopalliance .intercept .MethodInvocation ;
2124
2225import org .springframework .beans .factory .ObjectProvider ;
2326import org .springframework .beans .factory .config .BeanDefinition ;
2427import org .springframework .context .ApplicationContext ;
2528import org .springframework .context .annotation .Bean ;
2629import org .springframework .context .annotation .Configuration ;
2730import org .springframework .context .annotation .Role ;
31+ import org .springframework .expression .EvaluationContext ;
32+ import org .springframework .expression .Expression ;
33+ import org .springframework .expression .ExpressionParser ;
2834import org .springframework .security .access .expression .method .DefaultMethodSecurityExpressionHandler ;
2935import org .springframework .security .access .expression .method .MethodSecurityExpressionHandler ;
3036import org .springframework .security .authorization .AuthorizationEventPublisher ;
3642import org .springframework .security .authorization .method .PreAuthorizeAuthorizationManager ;
3743import org .springframework .security .authorization .method .PreFilterAuthorizationMethodInterceptor ;
3844import org .springframework .security .config .core .GrantedAuthorityDefaults ;
45+ import org .springframework .security .core .Authentication ;
3946import org .springframework .security .core .context .SecurityContextHolderStrategy ;
47+ import org .springframework .util .function .SingletonSupplier ;
4048
4149/**
4250 * Base {@link Configuration} for enabling Spring Security Method Security.
@@ -59,7 +67,7 @@ static MethodInterceptor preFilterAuthorizationMethodInterceptor(
5967 PreFilterAuthorizationMethodInterceptor preFilter = new PreFilterAuthorizationMethodInterceptor ();
6068 strategyProvider .ifAvailable (preFilter ::setSecurityContextHolderStrategy );
6169 preFilter .setExpressionHandler (
62- expressionHandlerProvider . getIfAvailable (() -> defaultExpressionHandler ( defaultsProvider , context ) ));
70+ new DeferringMethodSecurityExpressionHandler ( expressionHandlerProvider , defaultsProvider , context ));
6371 return preFilter ;
6472 }
6573
@@ -73,7 +81,7 @@ static MethodInterceptor preAuthorizeAuthorizationMethodInterceptor(
7381 ObjectProvider <ObservationRegistry > registryProvider , ApplicationContext context ) {
7482 PreAuthorizeAuthorizationManager manager = new PreAuthorizeAuthorizationManager ();
7583 manager .setExpressionHandler (
76- expressionHandlerProvider . getIfAvailable (() -> defaultExpressionHandler ( defaultsProvider , context ) ));
84+ new DeferringMethodSecurityExpressionHandler ( expressionHandlerProvider , defaultsProvider , context ));
7785 AuthorizationManagerBeforeMethodInterceptor preAuthorize = AuthorizationManagerBeforeMethodInterceptor
7886 .preAuthorize (manager (manager , registryProvider ));
7987 strategyProvider .ifAvailable (preAuthorize ::setSecurityContextHolderStrategy );
@@ -91,7 +99,7 @@ static MethodInterceptor postAuthorizeAuthorizationMethodInterceptor(
9199 ObjectProvider <ObservationRegistry > registryProvider , ApplicationContext context ) {
92100 PostAuthorizeAuthorizationManager manager = new PostAuthorizeAuthorizationManager ();
93101 manager .setExpressionHandler (
94- expressionHandlerProvider . getIfAvailable (() -> defaultExpressionHandler ( defaultsProvider , context ) ));
102+ new DeferringMethodSecurityExpressionHandler ( expressionHandlerProvider , defaultsProvider , context ));
95103 AuthorizationManagerAfterMethodInterceptor postAuthorize = AuthorizationManagerAfterMethodInterceptor
96104 .postAuthorize (manager (manager , registryProvider ));
97105 strategyProvider .ifAvailable (postAuthorize ::setSecurityContextHolderStrategy );
@@ -108,7 +116,7 @@ static MethodInterceptor postFilterAuthorizationMethodInterceptor(
108116 PostFilterAuthorizationMethodInterceptor postFilter = new PostFilterAuthorizationMethodInterceptor ();
109117 strategyProvider .ifAvailable (postFilter ::setSecurityContextHolderStrategy );
110118 postFilter .setExpressionHandler (
111- expressionHandlerProvider . getIfAvailable (() -> defaultExpressionHandler ( defaultsProvider , context ) ));
119+ new DeferringMethodSecurityExpressionHandler ( expressionHandlerProvider , defaultsProvider , context ));
112120 return postFilter ;
113121 }
114122
@@ -125,4 +133,43 @@ static <T> AuthorizationManager<T> manager(AuthorizationManager<T> delegate,
125133 return new DeferringObservationAuthorizationManager <>(registryProvider , delegate );
126134 }
127135
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+
128175}
0 commit comments