经过Debug,最原始的过滤器链是Tomcat的ApplicationFilterChain。java
org.apache.catalina.core.ApplicationFilterChain implements javax.servlet.FilterChain { // 实例是一个 DispatchServlet private Servlet servlet; // 过滤器数组 private ApplicationFilterConfig[] filters = new ApplicationFilterConfig[0]; // 当前的过滤器位置 private int pos; // 过滤器总数 private int n; public void doFilter(ServletRequest request, ServletResponse response) { internalDoFilter(request,response); } private void internalDoFilter(ServletRequest request, ServletResponse response) { if (pos < n) { ApplicationFilterConfig filterConfig = filters[pos++]; Filter filter = filterConfig.getFilter(); filter.doFilter(request, response, this); } } }
这里面有6个过滤器,分别是web
0 ApplicationFilterConfig[name=characterEncodingFilter, filterClass=org.springframework.boot.web.servlet.filter.OrderedCharacterEncodingFilter] 1 ApplicationFilterConfig[name=hiddenHttpMethodFilter, filterClass=org.springframework.boot.web.servlet.filter.OrderedHiddenHttpMethodFilter] 2 ApplicationFilterConfig[name=httpPutFormContentFilter, filterClass=org.springframework.boot.web.servlet.filter.OrderedHttpPutFormContentFilter] 3 ApplicationFilterConfig[name=requestContextFilter, filterClass=org.springframework.boot.web.servlet.filter.OrderedRequestContextFilter] 4 ApplicationFilterConfig[name=springSecurityFilterChain, filterClass=org.springframework.boot.web.servlet.DelegatingFilterProxyRegistrationBean$1] 5 ApplicationFilterConfig[name=Tomcat WebSocket (JSR356) Filter, filterClass=org.apache.tomcat.websocket.server.WsFilter]
Spring boot 以“springSecurityFilterChain”为名字,向容器注入DelegatingFilterProxyRegistrationBean,这个bean被包装成ApplicationFilterConfig, 以便经过getFilter()获取Filter。spring
这里应该是动态代理(这个暂时没想清楚),当调用filter.doFilter的时候,这个filter其实是DelegatingFilterProxy。apache
public class DelegatingFilterProxy extends GenericFilterBean { private volatile Filter delegate; public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) { Filter delegateToUse = this.delegate; invokeDelegate(delegateToUse, request, response, filterChain); } protected void invokeDelegate( Filter delegate, ServletRequest request, ServletResponse response, FilterChain filterChain) throws ServletException, IOException { delegate.doFilter(request, response, filterChain); } }
这里的 delegate 毫无疑问是 FilterChainProxy。数组
FilterChainProxy就带着一开始的ApplicationFilterChain,开始本身的过滤生涯,doFilter...tomcat
public class FilterChainProxy extends GenericFilterBean { public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { doFilterInternal(request, response, chain); } private void doFilterInternal(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // wrap FirewalledRequest fwRequest = firewall .getFirewalledRequest((HttpServletRequest) request); HttpServletResponse fwResponse = firewall .getFirewalledResponse((HttpServletResponse) response); // 根据请求匹配 security 过滤器 List<Filter> filters = getFilters(fwRequest); // 若是没有配置 security 过滤器 if (filters == null || filters.size() == 0) { // reset fwRequest.reset(); // 那么继续原始的过滤器链 ApplicationFilterChain chain.doFilter(fwRequest, fwResponse); } VirtualFilterChain vfc = new VirtualFilterChain(fwRequest, chain, filters); vfc.doFilter(fwRequest, fwResponse); } }
没错,FilterChainProxy根据请求,匹配到好多security过滤器,并用他们建立出一条新的过滤链 VirtualFilterChain。websocket
private static class VirtualFilterChain implements FilterChain { // 原始的 ApplicationFilterChain private final FilterChain originalChain; // security filters private final List<Filter> additionalFilters; private final FirewalledRequest firewalledRequest; private final int size; private int currentPosition = 0; v @Override public void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException { // VirtualFilterChain 过滤完成 if (currentPosition == size) { // reset this.firewalledRequest.reset(); // 继续原始链 originalChain.doFilter(request, response); } // 执行过滤器 else { currentPosition++; Filter nextFilter = additionalFilters.get(currentPosition - 1); nextFilter.doFilter(request, response, this); } } }
而这条新过滤链的过滤器数组,正是socket
additionalFilters = {ArrayList@6631} size = 13 0 = {WebAsyncManagerIntegrationFilter@6634} 1 = {SecurityContextPersistenceFilter@6471} 2 = {HeaderWriterFilter@6470} 3 = {CsrfFilter@6469} 4 = {LogoutFilter@6468} 5 = {CustomUsernamePasswordAuthenticationFilter@6467} 6 = {UsernamePasswordAuthenticationFilter@6466} 7 = {RequestCacheAwareFilter@6465} 8 = {SecurityContextHolderAwareRequestFilter@6462} 9 = {AnonymousAuthenticationFilter@6458} 10 = {SessionManagementFilter@6457} 12 = {FilterSecurityInterceptor@6635} 11 = {ExceptionTranslationFilter@6455}