SpringSecurity中對過濾器的配置:addFilterBefore
SpringSecurity基於Filter技術,通過一系列內置的或自定義的安全Filter,實現接口的認證與授權。我們一定在使用的過程中,定義過WebSecurityConfigurerAdapter的擴展,為程序自定義配置邏輯。
比如,我們想要自定義基於JWT攔截的過濾器,我們可以通過addFilterBefore(jwtAuthenticationTokenFilter(), UsernamePasswordAuthenticationFilter.class);
的方式,將過濾器按照一定順序加入過濾器鏈。
addFilterBefore在HttpSecurity類中:
public HttpSecurity addFilterBefore(Filter filter,
Class<? extends Filter> beforeFilter) {
comparator.registerBefore(filter.getClass(), beforeFilter);
return addFilter(filter);
}
見名知義,意思是在指定的beforeFilter之前加入filter。這里的comparator是內置的一個用於比較注冊順序的一個類,可以大致看一看:可以看到構造器初始化了map,key為過濾器的類對象,value為order。
order的順序也是確定的,舉個例子,ChannelProcessingFilter的order值為100,后面每多一個,就加上100。
final class FilterComparator implements Comparator<Filter>, Serializable {
private static final int INITIAL_ORDER = 100;
private static final int ORDER_STEP = 100;
private final Map<String, Integer> filterToOrder = new HashMap<>();
FilterComparator() { //初始化了一些默認的Filter並規定的order
Step order = new Step(INITIAL_ORDER, ORDER_STEP);//越往下order越大
put(ChannelProcessingFilter.class, order.next()); //100
put(ConcurrentSessionFilter.class, order.next()); //200
put(WebAsyncManagerIntegrationFilter.class, order.next());
put(SecurityContextPersistenceFilter.class, order.next());
put(HeaderWriterFilter.class, order.next());
put(CorsFilter.class, order.next());
put(CsrfFilter.class, order.next());
put(LogoutFilter.class, order.next());
//...省略
}
compare方法定義了比較的規則:依照order排序,小的在前,大的在后。
public int compare(Filter lhs, Filter rhs) {
Integer left = getOrder(lhs.getClass());
Integer right = getOrder(rhs.getClass());
return left - right;
}
registerBefore
以registerBefore
為例,其他類似的還有registerAt,registerAfter
。
public void registerBefore(Class<? extends Filter> filter,
Class<? extends Filter> beforeFilter) {
Integer position = getOrder(beforeFilter);//得到要加入的filter的位置
if (position == null) {}
put(filter, position - 1);//將當的filter存入map
}
addFilter
向List<Filter>
中加入filter。
public HttpSecurity addFilter(Filter filter) {
Class<? extends Filter> filterClass = filter.getClass();
if (!comparator.isRegistered(filterClass)) {}
this.filters.add(filter);//向List<Filter> 中加入filter
return this;
}
在所有的Filter添加完成之后,Filter其實並沒有按照order進行排序,因為暫時還是按照讀取的順序進行加入的List,只有當執行了HttpSecurity.performBuild
之后,才形成按照order排序的Filter數組。
在進行sort之后,根據order進行排序,生成的列表List就是最終的Filter列表。