diff --git a/config/src/test/java/org/springframework/security/config/annotation/method/configuration/PrePostMethodSecurityConfigurationTests.java b/config/src/test/java/org/springframework/security/config/annotation/method/configuration/PrePostMethodSecurityConfigurationTests.java index eb637fdf682..4fa7b8a16e0 100644 --- a/config/src/test/java/org/springframework/security/config/annotation/method/configuration/PrePostMethodSecurityConfigurationTests.java +++ b/config/src/test/java/org/springframework/security/config/annotation/method/configuration/PrePostMethodSecurityConfigurationTests.java @@ -104,6 +104,8 @@ import static org.mockito.Mockito.clearInvocations; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; /** @@ -995,6 +997,18 @@ void autowireWhenAspectJAutoProxyAndFactoryBeanThenExactlyOneAdvisorPerAnnotatio "postFilterAuthorizationMethodInterceptor", "authorizeReturnObjectMethodInterceptor"); } + // gh-15651 + @Test + @WithMockUser(roles = "ADMIN") + public void adviseWhenPrePostEnabledThenEachInterceptorRunsExactlyOnce() { + this.spring.register(MethodSecurityServiceConfig.class, CustomMethodSecurityExpressionHandlerConfig.class) + .autowire(); + MethodSecurityExpressionHandler expressionHandler = this.spring.getContext() + .getBean(MethodSecurityExpressionHandler.class); + this.methodSecurityService.manyAnnotations(new ArrayList<>(Arrays.asList("harold", "jonathan", "tim", "bo"))); + verify(expressionHandler, times(4)).createEvaluationContext(any(Supplier.class), any()); + } + private static Consumer disallowBeanOverriding() { return (context) -> ((AnnotationConfigWebApplicationContext) context).setAllowBeanDefinitionOverriding(false); } @@ -1090,6 +1104,19 @@ MethodSecurityService methodSecurityService() { } @Configuration + @EnableMethodSecurity + static class CustomMethodSecurityExpressionHandlerConfig { + + private final MethodSecurityExpressionHandler expressionHandler = spy( + new DefaultMethodSecurityExpressionHandler()); + + @Bean + MethodSecurityExpressionHandler methodSecurityExpressionHandler() { + return this.expressionHandler; + } + + } + @EnableMethodSecurity static class CustomPermissionEvaluatorConfig {