|
@@ -29,14 +29,12 @@ import jakarta.servlet.http.HttpServletRequest;
|
|
|
import org.springframework.beans.BeanMetadataElement;
|
|
|
import org.springframework.beans.BeansException;
|
|
|
import org.springframework.beans.factory.FactoryBean;
|
|
|
-import org.springframework.beans.factory.aot.BeanRegistrationExcludeFilter;
|
|
|
import org.springframework.beans.factory.config.BeanDefinition;
|
|
|
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
|
|
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
|
|
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
|
|
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
|
|
|
import org.springframework.beans.factory.support.ManagedList;
|
|
|
-import org.springframework.beans.factory.support.RegisteredBean;
|
|
|
import org.springframework.context.ApplicationContext;
|
|
|
import org.springframework.context.ApplicationContextAware;
|
|
|
import org.springframework.context.annotation.Bean;
|
|
@@ -113,86 +111,67 @@ class WebMvcSecurityConfiguration implements WebMvcConfigurer, ApplicationContex
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- @Bean
|
|
|
- static SpringSecurityHandlerMappingIntrospectorBeanDefinitionRegistryPostProcessor springSecurityHandlerMappingIntrospectorBeanDefinitionRegistryPostProcessor() {
|
|
|
- return new SpringSecurityHandlerMappingIntrospectorBeanDefinitionRegistryPostProcessor();
|
|
|
- }
|
|
|
-
|
|
|
/**
|
|
|
- * Used to ensure Spring MVC request matching is cached. Creates a
|
|
|
- * {@link BeanDefinitionRegistryPostProcessor} that detects if a bean named
|
|
|
+ * Used to ensure Spring MVC request matching is cached.
|
|
|
+ *
|
|
|
+ * Creates a {@link BeanDefinitionRegistryPostProcessor} that detects if a bean named
|
|
|
* HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME is defined. If so, it moves the
|
|
|
* AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME to another bean name
|
|
|
* and then adds a {@link CompositeFilter} that contains
|
|
|
* {@link HandlerMappingIntrospector#createCacheFilter()} and the original
|
|
|
* FilterChainProxy under the original Bean name.
|
|
|
- *
|
|
|
* @return
|
|
|
*/
|
|
|
- static class SpringSecurityHandlerMappingIntrospectorBeanDefinitionRegistryPostProcessor
|
|
|
- implements BeanDefinitionRegistryPostProcessor {
|
|
|
-
|
|
|
- @Override
|
|
|
- public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
|
|
|
- if (!registry.containsBeanDefinition(HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME)) {
|
|
|
- return;
|
|
|
+ @Bean
|
|
|
+ static BeanDefinitionRegistryPostProcessor springSecurityHandlerMappingIntrospectorBeanDefinitionRegistryPostProcessor() {
|
|
|
+ return new BeanDefinitionRegistryPostProcessor() {
|
|
|
+ @Override
|
|
|
+ public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
|
|
|
}
|
|
|
|
|
|
- BeanDefinition hmiRequestTransformer = BeanDefinitionBuilder
|
|
|
- .rootBeanDefinition(HandlerMappingIntrospectorRequestTransformer.class)
|
|
|
- .addConstructorArgReference(HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME)
|
|
|
- .getBeanDefinition();
|
|
|
- registry.registerBeanDefinition(HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME + "RequestTransformer",
|
|
|
- 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());
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
|
|
|
+ @Override
|
|
|
+ public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
|
|
|
+ if (!registry.containsBeanDefinition(HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME)) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
|
|
|
- }
|
|
|
+ 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);
|
|
|
|
|
|
- /**
|
|
|
- * Used to exclude the
|
|
|
- * {@link SpringSecurityHandlerMappingIntrospectorBeanDefinitionRegistryPostProcessor}
|
|
|
- * from AOT processing. See <a href=
|
|
|
- * "https://github.com/spring-projects/spring-security/issues/14362">gh-14362</a>
|
|
|
- */
|
|
|
- static class SpringSecurityHandlerMappingIntrospectorBeanRegistrationExcludeFilter
|
|
|
- implements BeanRegistrationExcludeFilter {
|
|
|
+ if (!filterChainProxy.getResolvableType().isInstance(CompositeFilterChainProxy.class)) {
|
|
|
+ BeanDefinitionBuilder hmiCacheFilterBldr = BeanDefinitionBuilder
|
|
|
+ .rootBeanDefinition(HandlerMappingIntrospectorCacheFilterFactoryBean.class)
|
|
|
+ .setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
|
|
|
|
|
|
- @Override
|
|
|
- public boolean isExcludedFromAotProcessing(RegisteredBean registeredBean) {
|
|
|
- Class<?> beanClass = registeredBean.getBeanClass();
|
|
|
- return SpringSecurityHandlerMappingIntrospectorBeanDefinitionRegistryPostProcessor.class == beanClass;
|
|
|
- }
|
|
|
+ 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());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ };
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* {@link FactoryBean} to defer creation of
|
|
|
* {@link HandlerMappingIntrospector#createCacheFilter()}
|
|
|
*/
|
|
|
- static class HandlerMappingIntrospectorCachFilterFactoryBean
|
|
|
+ static class HandlerMappingIntrospectorCacheFilterFactoryBean
|
|
|
implements ApplicationContextAware, FactoryBean<Filter> {
|
|
|
|
|
|
private ApplicationContext applicationContext;
|