3939import org .springframework .security .web .FilterChainProxy ;
4040import org .springframework .security .web .FilterInvocation ;
4141import org .springframework .security .web .SecurityFilterChain ;
42+ import org .springframework .security .web .UnreachableFilterChainException ;
4243import org .springframework .security .web .access .ExceptionTranslationFilter ;
4344import org .springframework .security .web .access .intercept .AuthorizationFilter ;
4445import org .springframework .security .web .access .intercept .FilterInvocationSecurityMetadataSource ;
5354import org .springframework .security .web .servletapi .SecurityContextHolderAwareRequestFilter ;
5455import org .springframework .security .web .session .SessionManagementFilter ;
5556import org .springframework .security .web .util .matcher .AnyRequestMatcher ;
56- import org .springframework .security .web .util .matcher .RequestMatcher ;
5757
58- public class DefaultFilterChainValidator implements FilterChainProxy .FilterChainValidator {
58+ public final class DefaultFilterChainValidator implements FilterChainProxy .FilterChainValidator {
5959
6060 private static final Authentication TEST = new TestingAuthenticationToken ("" , "" , Collections .emptyList ());
6161
@@ -75,25 +75,33 @@ private void checkPathOrder(List<SecurityFilterChain> filterChains) {
7575 // Check that the universal pattern is listed at the end, if at all
7676 Iterator <SecurityFilterChain > chains = filterChains .iterator ();
7777 while (chains .hasNext ()) {
78- RequestMatcher matcher = ((DefaultSecurityFilterChain ) chains .next ()).getRequestMatcher ();
79- if (AnyRequestMatcher .INSTANCE .equals (matcher ) && chains .hasNext ()) {
80- throw new IllegalArgumentException ("A universal match pattern ('/**') is defined "
81- + " before other patterns in the filter chain, causing them to be ignored. Please check the "
82- + "ordering in your <security:http> namespace or FilterChainProxy bean configuration" );
78+ if (chains .next () instanceof DefaultSecurityFilterChain securityFilterChain ) {
79+ if (AnyRequestMatcher .INSTANCE .equals (securityFilterChain .getRequestMatcher ()) && chains .hasNext ()) {
80+ throw new UnreachableFilterChainException ("A universal match pattern ('/**') is defined "
81+ + " before other patterns in the filter chain, causing them to be ignored. Please check the "
82+ + "ordering in your <security:http> namespace or FilterChainProxy bean configuration" );
83+ }
8384 }
8485 }
8586 }
8687
8788 private void checkForDuplicateMatchers (List <SecurityFilterChain > chains ) {
88- while (chains .size () > 1 ) {
89- DefaultSecurityFilterChain chain = (DefaultSecurityFilterChain ) chains .remove (0 );
90- for (SecurityFilterChain test : chains ) {
91- if (chain .getRequestMatcher ().equals (((DefaultSecurityFilterChain ) test ).getRequestMatcher ())) {
92- throw new IllegalArgumentException ("The FilterChainProxy contains two filter chains using the"
93- + " matcher " + chain .getRequestMatcher () + ". If you are using multiple <http> namespace "
94- + "elements, you must use a 'pattern' attribute to define the request patterns to which they apply." );
89+ DefaultSecurityFilterChain filterChain = null ;
90+ for (SecurityFilterChain chain : chains ) {
91+ if (filterChain != null ) {
92+ if (chain instanceof DefaultSecurityFilterChain defaultChain ) {
93+ if (defaultChain .getRequestMatcher ().equals (filterChain .getRequestMatcher ())) {
94+ throw new UnreachableFilterChainException (
95+ "The FilterChainProxy contains two filter chains using the" + " matcher "
96+ + defaultChain .getRequestMatcher ()
97+ + ". If you are using multiple <http> namespace "
98+ + "elements, you must use a 'pattern' attribute to define the request patterns to which they apply." );
99+ }
95100 }
96101 }
102+ if (chain instanceof DefaultSecurityFilterChain defaultChain ) {
103+ filterChain = defaultChain ;
104+ }
97105 }
98106 }
99107
0 commit comments