16
16
package org .springframework .security .config .annotation .web .builders ;
17
17
18
18
import org .springframework .context .ApplicationContext ;
19
+ import org .springframework .core .OrderComparator ;
20
+ import org .springframework .core .Ordered ;
19
21
import org .springframework .http .HttpMethod ;
20
22
import org .springframework .security .authentication .AuthenticationManager ;
21
23
import org .springframework .security .authentication .AuthenticationProvider ;
78
80
import org .springframework .web .filter .CorsFilter ;
79
81
import org .springframework .web .servlet .handler .HandlerMappingIntrospector ;
80
82
83
+ import java .io .IOException ;
81
84
import java .util .ArrayList ;
82
85
import java .util .List ;
83
86
import java .util .Map ;
87
+
84
88
import javax .servlet .Filter ;
89
+ import javax .servlet .FilterChain ;
90
+ import javax .servlet .ServletException ;
91
+ import javax .servlet .ServletRequest ;
92
+ import javax .servlet .ServletResponse ;
85
93
import javax .servlet .http .HttpServletRequest ;
86
94
87
95
/**
@@ -125,9 +133,9 @@ public final class HttpSecurity extends
125
133
implements SecurityBuilder <DefaultSecurityFilterChain >,
126
134
HttpSecurityBuilder <HttpSecurity > {
127
135
private final RequestMatcherConfigurer requestMatcherConfigurer ;
128
- private List <Filter > filters = new ArrayList <>();
136
+ private List <OrderedFilter > filters = new ArrayList <>();
129
137
private RequestMatcher requestMatcher = AnyRequestMatcher .INSTANCE ;
130
- private FilterComparator comparator = new FilterComparator ();
138
+ private FilterOrderRegistration filterOrders = new FilterOrderRegistration ();
131
139
132
140
/**
133
141
* Creates a new instance
@@ -2528,8 +2536,12 @@ protected void beforeConfigure() throws Exception {
2528
2536
2529
2537
@ Override
2530
2538
protected DefaultSecurityFilterChain performBuild () {
2531
- filters .sort (comparator );
2532
- return new DefaultSecurityFilterChain (requestMatcher , filters );
2539
+ this .filters .sort (OrderComparator .INSTANCE );
2540
+ List <Filter > sortedFilters = new ArrayList <>(this .filters .size ());
2541
+ for (Filter filter : this .filters ) {
2542
+ sortedFilters .add (((OrderedFilter ) filter ).filter );
2543
+ }
2544
+ return new DefaultSecurityFilterChain (this .requestMatcher , sortedFilters );
2533
2545
}
2534
2546
2535
2547
/*
@@ -2570,8 +2582,7 @@ private AuthenticationManagerBuilder getAuthenticationRegistry() {
2570
2582
* .servlet.Filter, java.lang.Class)
2571
2583
*/
2572
2584
public HttpSecurity addFilterAfter (Filter filter , Class <? extends Filter > afterFilter ) {
2573
- comparator .registerAfter (filter .getClass (), afterFilter );
2574
- return addFilter (filter );
2585
+ return addFilterAtOffsetOf (filter , 1 , afterFilter );
2575
2586
}
2576
2587
2577
2588
/*
@@ -2583,8 +2594,13 @@ public HttpSecurity addFilterAfter(Filter filter, Class<? extends Filter> afterF
2583
2594
*/
2584
2595
public HttpSecurity addFilterBefore (Filter filter ,
2585
2596
Class <? extends Filter > beforeFilter ) {
2586
- comparator .registerBefore (filter .getClass (), beforeFilter );
2587
- return addFilter (filter );
2597
+ return addFilterAtOffsetOf (filter , -1 , beforeFilter );
2598
+ }
2599
+
2600
+ private HttpSecurity addFilterAtOffsetOf (Filter filter , int offset , Class <? extends Filter > registeredFilter ) {
2601
+ int order = this .filterOrders .getOrder (registeredFilter ) + offset ;
2602
+ this .filters .add (new OrderedFilter (filter , order ));
2603
+ return this ;
2588
2604
}
2589
2605
2590
2606
/*
@@ -2595,14 +2611,12 @@ public HttpSecurity addFilterBefore(Filter filter,
2595
2611
* servlet.Filter)
2596
2612
*/
2597
2613
public HttpSecurity addFilter (Filter filter ) {
2598
- Class <? extends Filter > filterClass = filter .getClass ();
2599
- if (!comparator .isRegistered (filterClass )) {
2600
- throw new IllegalArgumentException (
2601
- "The Filter class "
2602
- + filterClass .getName ()
2603
- + " does not have a registered order and cannot be added without a specified order. Consider using addFilterBefore or addFilterAfter instead." );
2614
+ Integer order = this .filterOrders .getOrder (filter .getClass ());
2615
+ if (order == null ) {
2616
+ throw new IllegalArgumentException ("The Filter class " + filter .getClass ().getName ()
2617
+ + " does not have a registered order and cannot be added without a specified order. Consider using addFilterBefore or addFilterAfter instead." );
2604
2618
}
2605
- this .filters .add (filter );
2619
+ this .filters .add (new OrderedFilter ( filter , order ) );
2606
2620
return this ;
2607
2621
}
2608
2622
@@ -2626,8 +2640,7 @@ public HttpSecurity addFilter(Filter filter) {
2626
2640
* @return the {@link HttpSecurity} for further customizations
2627
2641
*/
2628
2642
public HttpSecurity addFilterAt (Filter filter , Class <? extends Filter > atFilter ) {
2629
- this .comparator .registerAt (filter .getClass (), atFilter );
2630
- return addFilter (filter );
2643
+ return addFilterAtOffsetOf (filter , 0 , atFilter );
2631
2644
}
2632
2645
2633
2646
/**
@@ -3023,4 +3036,38 @@ private <C extends SecurityConfigurerAdapter<DefaultSecurityFilterChain, HttpSec
3023
3036
}
3024
3037
return apply (configurer );
3025
3038
}
3039
+
3040
+ /*
3041
+ * A Filter that implements Ordered to be sorted. After sorting occurs, the original
3042
+ * filter is what is used by FilterChainProxy
3043
+ */
3044
+ private static final class OrderedFilter implements Ordered , Filter {
3045
+
3046
+ private final Filter filter ;
3047
+
3048
+ private final int order ;
3049
+
3050
+ private OrderedFilter (Filter filter , int order ) {
3051
+ this .filter = filter ;
3052
+ this .order = order ;
3053
+ }
3054
+
3055
+ @ Override
3056
+ public void doFilter (ServletRequest servletRequest , ServletResponse servletResponse , FilterChain filterChain )
3057
+ throws IOException , ServletException {
3058
+ this .filter .doFilter (servletRequest , servletResponse , filterChain );
3059
+ }
3060
+
3061
+ @ Override
3062
+ public int getOrder () {
3063
+ return this .order ;
3064
+ }
3065
+
3066
+ @ Override
3067
+ public String toString () {
3068
+ return "OrderedFilter{" + "filter=" + this .filter + ", order=" + this .order + '}' ;
3069
+ }
3070
+
3071
+ }
3072
+
3026
3073
}
0 commit comments