From 92af758f1f09149b8840169cdee7d3b03a23ca8a Mon Sep 17 00:00:00 2001 From: Marcus Hert Da Coregio Date: Tue, 26 Dec 2023 15:58:16 -0300 Subject: [PATCH] Make springSecurityHandlerMappingIntrospectorBeanDefinitionRegistryPostProcessor passive Instead of excluding the bean from AOT processing, we avoid redefining the beans if they are present or in the expected state. Issue gh-14362 --- .../WebMvcSecurityConfiguration.java | 42 ++++++++++--------- ...bMvcSecurityConfigurationRuntimeHints.java | 6 ++- ...ecurityConfigurationRuntimeHintsTests.java | 8 ++++ .../hint/WebTestUtilsTestRuntimeHints.java | 2 +- .../WebTestUtilsTestRuntimeHintsTests.java | 3 +- 5 files changed, 38 insertions(+), 23 deletions(-) diff --git a/config/src/main/java/org/springframework/security/config/annotation/web/configuration/WebMvcSecurityConfiguration.java b/config/src/main/java/org/springframework/security/config/annotation/web/configuration/WebMvcSecurityConfiguration.java index bdb788fcd7..ec33c902f5 100644 --- a/config/src/main/java/org/springframework/security/config/annotation/web/configuration/WebMvcSecurityConfiguration.java +++ b/config/src/main/java/org/springframework/security/config/annotation/web/configuration/WebMvcSecurityConfiguration.java @@ -135,30 +135,34 @@ class WebMvcSecurityConfiguration implements WebMvcConfigurer, ApplicationContex return; } - BeanDefinition hmiRequestTransformer = BeanDefinitionBuilder - .rootBeanDefinition(HandlerMappingIntrospectorRequestTransformer.class) - .addConstructorArgReference(HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME) - .getBeanDefinition(); - registry.registerBeanDefinition(HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME + "RequestTransformer", - hmiRequestTransformer); + String hmiRequestTransformerBeanName = HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME + "RequestTransformer"; + if (!registry.containsBeanDefinition(hmiRequestTransformerBeanName)) { + BeanDefinition hmiRequestTransformer = BeanDefinitionBuilder + .rootBeanDefinition(HandlerMappingIntrospectorRequestTransformer.class) + .addConstructorArgReference(HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME) + .getBeanDefinition(); + registry.registerBeanDefinition(hmiRequestTransformerBeanName, hmiRequestTransformer); + } BeanDefinition filterChainProxy = registry .getBeanDefinition(AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME); - BeanDefinitionBuilder hmiCacheFilterBldr = BeanDefinitionBuilder - .rootBeanDefinition(HandlerMappingIntrospectorCachFilterFactoryBean.class) - .setRole(BeanDefinition.ROLE_INFRASTRUCTURE); + if (!filterChainProxy.getResolvableType().isInstance(CompositeFilterChainProxy.class)) { + BeanDefinitionBuilder hmiCacheFilterBldr = BeanDefinitionBuilder + .rootBeanDefinition(HandlerMappingIntrospectorCacheFilterFactoryBean.class) + .setRole(BeanDefinition.ROLE_INFRASTRUCTURE); - ManagedList filters = new ManagedList<>(); - filters.add(hmiCacheFilterBldr.getBeanDefinition()); - filters.add(filterChainProxy); - BeanDefinitionBuilder compositeSpringSecurityFilterChainBldr = BeanDefinitionBuilder - .rootBeanDefinition(CompositeFilterChainProxy.class) - .addConstructorArgValue(filters); + ManagedList filters = new ManagedList<>(); + filters.add(hmiCacheFilterBldr.getBeanDefinition()); + filters.add(filterChainProxy); + BeanDefinitionBuilder compositeSpringSecurityFilterChainBldr = BeanDefinitionBuilder + .rootBeanDefinition(CompositeFilterChainProxy.class) + .addConstructorArgValue(filters); - registry.removeBeanDefinition(AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME); - registry.registerBeanDefinition(AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME, - compositeSpringSecurityFilterChainBldr.getBeanDefinition()); + registry.removeBeanDefinition(AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME); + registry.registerBeanDefinition(AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME, + compositeSpringSecurityFilterChainBldr.getBeanDefinition()); + } } }; } @@ -167,7 +171,7 @@ class WebMvcSecurityConfiguration implements WebMvcConfigurer, ApplicationContex * {@link FactoryBean} to defer creation of * {@link HandlerMappingIntrospector#createCacheFilter()} */ - static class HandlerMappingIntrospectorCachFilterFactoryBean + static class HandlerMappingIntrospectorCacheFilterFactoryBean implements ApplicationContextAware, FactoryBean { private ApplicationContext applicationContext; diff --git a/config/src/main/java/org/springframework/security/config/aot/hint/WebMvcSecurityConfigurationRuntimeHints.java b/config/src/main/java/org/springframework/security/config/aot/hint/WebMvcSecurityConfigurationRuntimeHints.java index 216f06d97e..9d292b2477 100644 --- a/config/src/main/java/org/springframework/security/config/aot/hint/WebMvcSecurityConfigurationRuntimeHints.java +++ b/config/src/main/java/org/springframework/security/config/aot/hint/WebMvcSecurityConfigurationRuntimeHints.java @@ -34,7 +34,11 @@ class WebMvcSecurityConfigurationRuntimeHints implements RuntimeHintsRegistrar { hints.reflection() .registerType(TypeReference .of("org.springframework.security.config.annotation.web.configuration.WebMvcSecurityConfiguration$CompositeFilterChainProxy"), - MemberCategory.INVOKE_DECLARED_METHODS, MemberCategory.INVOKE_DECLARED_CONSTRUCTORS); + MemberCategory.INVOKE_DECLARED_CONSTRUCTORS); + hints.reflection() + .registerType(TypeReference + .of("org.springframework.security.config.annotation.web.configuration.WebMvcSecurityConfiguration$HandlerMappingIntrospectorCacheFilterFactoryBean"), + MemberCategory.INVOKE_DECLARED_CONSTRUCTORS); } } diff --git a/config/src/test/java/org/springframework/security/config/aot/hint/WebMvcSecurityConfigurationRuntimeHintsTests.java b/config/src/test/java/org/springframework/security/config/aot/hint/WebMvcSecurityConfigurationRuntimeHintsTests.java index 57f9a82750..906deec0e9 100644 --- a/config/src/test/java/org/springframework/security/config/aot/hint/WebMvcSecurityConfigurationRuntimeHintsTests.java +++ b/config/src/test/java/org/springframework/security/config/aot/hint/WebMvcSecurityConfigurationRuntimeHintsTests.java @@ -53,4 +53,12 @@ class WebMvcSecurityConfigurationRuntimeHintsTests { .withMemberCategory(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS)).accepts(this.hints); } + @Test + void handlerMappingIntrospectorCacheFilterFactoryBeanHasHints() { + assertThat(RuntimeHintsPredicates.reflection() + .onType(TypeReference + .of("org.springframework.security.config.annotation.web.configuration.WebMvcSecurityConfiguration$HandlerMappingIntrospectorCacheFilterFactoryBean")) + .withMemberCategory(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS)).accepts(this.hints); + } + } diff --git a/test/src/main/java/org/springframework/security/test/aot/hint/WebTestUtilsTestRuntimeHints.java b/test/src/main/java/org/springframework/security/test/aot/hint/WebTestUtilsTestRuntimeHints.java index d01c72d9b9..2210b36363 100644 --- a/test/src/main/java/org/springframework/security/test/aot/hint/WebTestUtilsTestRuntimeHints.java +++ b/test/src/main/java/org/springframework/security/test/aot/hint/WebTestUtilsTestRuntimeHints.java @@ -50,7 +50,7 @@ class WebTestUtilsTestRuntimeHints implements TestRuntimeHintsRegistrar { hints.reflection() .registerType(TypeReference .of("org.springframework.security.config.annotation.web.configuration.WebMvcSecurityConfiguration$CompositeFilterChainProxy"), - MemberCategory.INVOKE_DECLARED_METHODS, MemberCategory.INVOKE_DECLARED_CONSTRUCTORS); + MemberCategory.INVOKE_DECLARED_METHODS); } private void registerCsrfTokenRepositoryHints(RuntimeHints hints) { diff --git a/test/src/test/java/org/springframework/security/test/aot/hint/WebTestUtilsTestRuntimeHintsTests.java b/test/src/test/java/org/springframework/security/test/aot/hint/WebTestUtilsTestRuntimeHintsTests.java index e29fc9308a..53954aab57 100644 --- a/test/src/test/java/org/springframework/security/test/aot/hint/WebTestUtilsTestRuntimeHintsTests.java +++ b/test/src/test/java/org/springframework/security/test/aot/hint/WebTestUtilsTestRuntimeHintsTests.java @@ -62,8 +62,7 @@ class WebTestUtilsTestRuntimeHintsTests { assertThat(RuntimeHintsPredicates.reflection() .onType(TypeReference .of("org.springframework.security.config.annotation.web.configuration.WebMvcSecurityConfiguration$CompositeFilterChainProxy")) - .withMemberCategories(MemberCategory.INVOKE_DECLARED_METHODS, MemberCategory.INVOKE_DECLARED_CONSTRUCTORS)) - .accepts(this.hints); + .withMemberCategory(MemberCategory.INVOKE_DECLARED_METHODS)).accepts(this.hints); } @Test