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
@@ -2532,8 +2540,12 @@ protected void beforeConfigure() throws Exception {
2532
2540
2533
2541
@ Override
2534
2542
protected DefaultSecurityFilterChain performBuild () {
2535
- filters .sort (comparator );
2536
- return new DefaultSecurityFilterChain (requestMatcher , filters );
2543
+ this .filters .sort (OrderComparator .INSTANCE );
2544
+ List <Filter > sortedFilters = new ArrayList <>(this .filters .size ());
2545
+ for (Filter filter : this .filters ) {
2546
+ sortedFilters .add (((OrderedFilter ) filter ).filter );
2547
+ }
2548
+ return new DefaultSecurityFilterChain (this .requestMatcher , sortedFilters );
2537
2549
}
2538
2550
2539
2551
/*
@@ -2574,8 +2586,7 @@ private AuthenticationManagerBuilder getAuthenticationRegistry() {
2574
2586
* .servlet.Filter, java.lang.Class)
2575
2587
*/
2576
2588
public HttpSecurity addFilterAfter (Filter filter , Class <? extends Filter > afterFilter ) {
2577
- comparator .registerAfter (filter .getClass (), afterFilter );
2578
- return addFilter (filter );
2589
+ return addFilterAtOffsetOf (filter , 1 , afterFilter );
2579
2590
}
2580
2591
2581
2592
/*
@@ -2587,8 +2598,13 @@ public HttpSecurity addFilterAfter(Filter filter, Class<? extends Filter> afterF
2587
2598
*/
2588
2599
public HttpSecurity addFilterBefore (Filter filter ,
2589
2600
Class <? extends Filter > beforeFilter ) {
2590
- comparator .registerBefore (filter .getClass (), beforeFilter );
2591
- return addFilter (filter );
2601
+ return addFilterAtOffsetOf (filter , -1 , beforeFilter );
2602
+ }
2603
+
2604
+ private HttpSecurity addFilterAtOffsetOf (Filter filter , int offset , Class <? extends Filter > registeredFilter ) {
2605
+ int order = this .filterOrders .getOrder (registeredFilter ) + offset ;
2606
+ this .filters .add (new OrderedFilter (filter , order ));
2607
+ return this ;
2592
2608
}
2593
2609
2594
2610
/*
@@ -2599,14 +2615,12 @@ public HttpSecurity addFilterBefore(Filter filter,
2599
2615
* servlet.Filter)
2600
2616
*/
2601
2617
public HttpSecurity addFilter (Filter filter ) {
2602
- Class <? extends Filter > filterClass = filter .getClass ();
2603
- if (!comparator .isRegistered (filterClass )) {
2604
- throw new IllegalArgumentException (
2605
- "The Filter class "
2606
- + filterClass .getName ()
2607
- + " does not have a registered order and cannot be added without a specified order. Consider using addFilterBefore or addFilterAfter instead." );
2618
+ Integer order = this .filterOrders .getOrder (filter .getClass ());
2619
+ if (order == null ) {
2620
+ throw new IllegalArgumentException ("The Filter class " + filter .getClass ().getName ()
2621
+ + " does not have a registered order and cannot be added without a specified order. Consider using addFilterBefore or addFilterAfter instead." );
2608
2622
}
2609
- this .filters .add (filter );
2623
+ this .filters .add (new OrderedFilter ( filter , order ) );
2610
2624
return this ;
2611
2625
}
2612
2626
@@ -2630,8 +2644,7 @@ public HttpSecurity addFilter(Filter filter) {
2630
2644
* @return the {@link HttpSecurity} for further customizations
2631
2645
*/
2632
2646
public HttpSecurity addFilterAt (Filter filter , Class <? extends Filter > atFilter ) {
2633
- this .comparator .registerAt (filter .getClass (), atFilter );
2634
- return addFilter (filter );
2647
+ return addFilterAtOffsetOf (filter , 0 , atFilter );
2635
2648
}
2636
2649
2637
2650
/**
@@ -3027,4 +3040,38 @@ private <C extends SecurityConfigurerAdapter<DefaultSecurityFilterChain, HttpSec
3027
3040
}
3028
3041
return apply (configurer );
3029
3042
}
3043
+
3044
+ /*
3045
+ * A Filter that implements Ordered to be sorted. After sorting occurs, the original
3046
+ * filter is what is used by FilterChainProxy
3047
+ */
3048
+ private static final class OrderedFilter implements Ordered , Filter {
3049
+
3050
+ private final Filter filter ;
3051
+
3052
+ private final int order ;
3053
+
3054
+ private OrderedFilter (Filter filter , int order ) {
3055
+ this .filter = filter ;
3056
+ this .order = order ;
3057
+ }
3058
+
3059
+ @ Override
3060
+ public void doFilter (ServletRequest servletRequest , ServletResponse servletResponse , FilterChain filterChain )
3061
+ throws IOException , ServletException {
3062
+ this .filter .doFilter (servletRequest , servletResponse , filterChain );
3063
+ }
3064
+
3065
+ @ Override
3066
+ public int getOrder () {
3067
+ return this .order ;
3068
+ }
3069
+
3070
+ @ Override
3071
+ public String toString () {
3072
+ return "OrderedFilter{" + "filter=" + this .filter + ", order=" + this .order + '}' ;
3073
+ }
3074
+
3075
+ }
3076
+
3030
3077
}
0 commit comments