@ -16,9 +16,14 @@
@@ -16,9 +16,14 @@
package org.springframework.security.config.annotation.web.configuration ;
import java.io.IOException ;
import java.util.List ;
import jakarta.servlet.Filter ;
import jakarta.servlet.FilterChain ;
import jakarta.servlet.ServletException ;
import jakarta.servlet.ServletRequest ;
import jakarta.servlet.ServletResponse ;
import jakarta.servlet.http.HttpServletRequest ;
import org.springframework.beans.BeanMetadataElement ;
@ -26,7 +31,6 @@ import org.springframework.beans.BeansException;
@@ -26,7 +31,6 @@ import org.springframework.beans.BeansException;
import org.springframework.beans.factory.FactoryBean ;
import org.springframework.beans.factory.config.BeanDefinition ;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory ;
import org.springframework.beans.factory.config.RuntimeBeanReference ;
import org.springframework.beans.factory.support.BeanDefinitionBuilder ;
import org.springframework.beans.factory.support.BeanDefinitionRegistry ;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor ;
@ -42,6 +46,8 @@ import org.springframework.security.web.FilterChainProxy;
@@ -42,6 +46,8 @@ import org.springframework.security.web.FilterChainProxy;
import org.springframework.security.web.SecurityFilterChain ;
import org.springframework.security.web.access.HandlerMappingIntrospectorRequestTransformer ;
import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer ;
import org.springframework.security.web.firewall.HttpFirewall ;
import org.springframework.security.web.firewall.RequestRejectedHandler ;
import org.springframework.security.web.method.annotation.AuthenticationPrincipalArgumentResolver ;
import org.springframework.security.web.method.annotation.CsrfTokenArgumentResolver ;
import org.springframework.security.web.method.annotation.CurrentSecurityContextArgumentResolver ;
@ -135,11 +141,8 @@ class WebMvcSecurityConfiguration implements WebMvcConfigurer, ApplicationContex
@@ -135,11 +141,8 @@ class WebMvcSecurityConfiguration implements WebMvcConfigurer, ApplicationContex
registry . registerBeanDefinition ( HANDLER_MAPPING_INTROSPECTOR_BEAN_NAME + "RequestTransformer" ,
hmiRequestTransformer ) ;
String filterChainProxyBeanName = AbstractSecurityWebApplicationInitializer . DEFAULT_FILTER_NAME
+ "Proxy" ;
BeanDefinition filterChainProxy = registry
. getBeanDefinition ( AbstractSecurityWebApplicationInitializer . DEFAULT_FILTER_NAME ) ;
registry . registerBeanDefinition ( filterChainProxyBeanName , filterChainProxy ) ;
BeanDefinitionBuilder hmiCacheFilterBldr = BeanDefinitionBuilder
. rootBeanDefinition ( HandlerMappingIntrospectorCachFilterFactoryBean . class )
@ -147,9 +150,9 @@ class WebMvcSecurityConfiguration implements WebMvcConfigurer, ApplicationContex
@@ -147,9 +150,9 @@ class WebMvcSecurityConfiguration implements WebMvcConfigurer, ApplicationContex
ManagedList < BeanMetadataElement > filters = new ManagedList < > ( ) ;
filters . add ( hmiCacheFilterBldr . getBeanDefinition ( ) ) ;
filters . add ( new RuntimeBeanReference ( filterChainProxyBeanName ) ) ;
filters . add ( filterChainProxy ) ;
BeanDefinitionBuilder compositeSpringSecurityFilterChainBldr = BeanDefinitionBuilder
. rootBeanDefinition ( SpringSecurityFilter CompositeFilter. class )
. rootBeanDefinition ( CompositeFilterChainProxy . class )
. addConstructorArgValue ( filters ) ;
registry . removeBeanDefinition ( AbstractSecurityWebApplicationInitializer . DEFAULT_FILTER_NAME ) ;
@ -188,21 +191,73 @@ class WebMvcSecurityConfiguration implements WebMvcConfigurer, ApplicationContex
@@ -188,21 +191,73 @@ class WebMvcSecurityConfiguration implements WebMvcConfigurer, ApplicationContex
}
/ * *
* Extension to { @link CompositeFilter } to expose private methods used by Spring
* Security ' s test support
* Extends { @link FilterChainProxy } to provide as much passivity as possible but
* delegates to { @link CompositeFilter } for
* { @link # doFilter ( ServletRequest , ServletResponse , FilterChain ) } .
* /
static class SpringSecurityFilter CompositeFilter extends Composite Filter {
static class CompositeFilterChainProxy extends FilterChainProxy {
private FilterChainProxy springSecurityFilterChain ;
/ * *
* Used for { @link # doFilter ( ServletRequest , ServletResponse , FilterChain ) }
* /
private final Filter doFilterDelegate ;
SpringSecurityFilterCompositeFilter ( List < ? extends Filter > filters ) {
setFilters ( filters ) ; // for the parent
private final FilterChainProxy springSecurityFilterChain ;
/ * *
* Creates a new instance
* @param filters the Filters to delegate to . One of which must be
* FilterChainProxy .
* /
CompositeFilterChainProxy ( List < ? extends Filter > filters ) {
this . doFilterDelegate = createDoFilterDelegate ( filters ) ;
this . springSecurityFilterChain = findFilterChainProxy ( filters ) ;
}
@Override
public void setFilters ( List < ? extends Filter > filters ) {
super . setFilters ( filters ) ;
this . springSecurityFilterChain = findFilterChainProxy ( filters ) ;
public void afterPropertiesSet ( ) {
this . springSecurityFilterChain . afterPropertiesSet ( ) ;
}
@Override
public void doFilter ( ServletRequest request , ServletResponse response , FilterChain chain )
throws IOException , ServletException {
this . doFilterDelegate . doFilter ( request , response , chain ) ;
}
@Override
public List < Filter > getFilters ( String url ) {
return this . springSecurityFilterChain . getFilters ( url ) ;
}
@Override
public List < SecurityFilterChain > getFilterChains ( ) {
return this . springSecurityFilterChain . getFilterChains ( ) ;
}
@Override
public void setSecurityContextHolderStrategy ( SecurityContextHolderStrategy securityContextHolderStrategy ) {
this . springSecurityFilterChain . setSecurityContextHolderStrategy ( securityContextHolderStrategy ) ;
}
@Override
public void setFilterChainValidator ( FilterChainValidator filterChainValidator ) {
this . springSecurityFilterChain . setFilterChainValidator ( filterChainValidator ) ;
}
@Override
public void setFilterChainDecorator ( FilterChainDecorator filterChainDecorator ) {
this . springSecurityFilterChain . setFilterChainDecorator ( filterChainDecorator ) ;
}
@Override
public void setFirewall ( HttpFirewall firewall ) {
this . springSecurityFilterChain . setFirewall ( firewall ) ;
}
@Override
public void setRequestRejectedHandler ( RequestRejectedHandler requestRejectedHandler ) {
this . springSecurityFilterChain . setRequestRejectedHandler ( requestRejectedHandler ) ;
}
/ * *
@ -212,7 +267,7 @@ class WebMvcSecurityConfiguration implements WebMvcConfigurer, ApplicationContex
@@ -212,7 +267,7 @@ class WebMvcSecurityConfiguration implements WebMvcConfigurer, ApplicationContex
* @return
* /
private List < ? extends Filter > getFilters ( HttpServletRequest request ) {
List < SecurityFilterChain > filterChains = getFilterChainProxy ( ) . getFilterChains ( ) ;
List < SecurityFilterChain > filterChains = this . springSecurityFilterChain . getFilterChains ( ) ;
for ( SecurityFilterChain chain : filterChains ) {
if ( chain . matches ( request ) ) {
return chain . getFilters ( ) ;
@ -222,11 +277,14 @@ class WebMvcSecurityConfiguration implements WebMvcConfigurer, ApplicationContex
@@ -222,11 +277,14 @@ class WebMvcSecurityConfiguration implements WebMvcConfigurer, ApplicationContex
}
/ * *
* Used by Spring Security ' s Test support to find the FilterChainProxy
* @return
* Creates the Filter to delegate to for doFilter
* @param filters the Filters to delegate to .
* @return the Filter for doFilter
* /
private FilterChainProxy getFilterChainProxy ( ) {
return this . springSecurityFilterChain ;
private static Filter createDoFilterDelegate ( List < ? extends Filter > filters ) {
CompositeFilter delegate = new CompositeFilter ( ) ;
delegate . setFilters ( filters ) ;
return delegate ;
}
/ * *