Browse Source

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
Marcus Hert Da Coregio 1 year ago
parent
commit
92af758f1f

+ 25 - 21
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);
-
-				ManagedList<BeanMetadataElement> 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());
+				if (!filterChainProxy.getResolvableType().isInstance(CompositeFilterChainProxy.class)) {
+					BeanDefinitionBuilder hmiCacheFilterBldr = BeanDefinitionBuilder
+						.rootBeanDefinition(HandlerMappingIntrospectorCacheFilterFactoryBean.class)
+						.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
+
+					ManagedList<BeanMetadataElement> 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());
+				}
 			}
 		};
 	}
@@ -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<Filter> {
 
 		private ApplicationContext applicationContext;

+ 5 - 1
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);
 	}
 
 }

+ 8 - 0
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);
+	}
+
 }

+ 1 - 1
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) {

+ 1 - 2
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