源码阅读

  • FilterChain 是一个接口,定义有doFilter方法。
void doFilter(ServletRequest var1, ServletResponse var2) throws IOException, ServletException;
  • ApplicationFilterChain implement FilterChain

ApplicationFilterChain 里的doFilter 方法主要调用了this.internalDoFilter(request, response)

public void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException {if (Globals.IS_SECURITY_ENABLED) {ServletRequest req = request;ServletResponse res = response;try {AccessController.doPrivileged(() -> {this.internalDoFilter(req, res);return null;});} catch (PrivilegedActionException var7) {Exception e = var7.getException();if (e instanceof ServletException) {throw (ServletException)e;}if (e instanceof IOException) {throw (IOException)e;}if (e instanceof RuntimeException) {throw (RuntimeException)e;}throw new ServletException(e.getMessage(), e);}} else {this.internalDoFilter(request, response);}}

internalDoFilter方法里主要也是filter.doFilter(request, response, this);

private void internalDoFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException {。。。。filter.doFilter(request, response, this);。。。。}
  • abstract class GenericFilterBean implements Filter, BeanNameAware, EnvironmentAware, EnvironmentCapable, ServletContextAware, InitializingBean, DisposableBean 是一个通用过滤器抽象类。
  • abstract class OncePerRequestFilter extends GenericFilterBean 也是一个抽象类,每个请求过滤器一次。

主要doFilter

 public final void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws ServletException, IOException {if (request instanceof HttpServletRequest && response instanceof HttpServletResponse) {HttpServletRequest httpRequest = (HttpServletRequest)request;HttpServletResponse httpResponse = (HttpServletResponse)response;String alreadyFilteredAttributeName = this.getAlreadyFilteredAttributeName();boolean hasAlreadyFilteredAttribute = request.getAttribute(alreadyFilteredAttributeName) != null;if (!this.skipDispatch(httpRequest) && !this.shouldNotFilter(httpRequest)) {if (hasAlreadyFilteredAttribute) {if (DispatcherType.ERROR.equals(request.getDispatcherType())) {this.doFilterNestedErrorDispatch(httpRequest, httpResponse, filterChain);return;}filterChain.doFilter(request, response);} else {request.setAttribute(alreadyFilteredAttributeName, Boolean.TRUE);try {this.doFilterInternal(httpRequest, httpResponse, filterChain);} finally {request.removeAttribute(alreadyFilteredAttributeName);}}} else {filterChain.doFilter(request, response);}} else {throw new ServletException("OncePerRequestFilter just supports HTTP requests");}}
  • class CharacterEncodingFilter extends OncePerRequestFilter,字符编码过滤器。
  • class WebMvcMetricsFilter extends OncePerRequestFilter,Web Mvc 指标过滤器。
  • class FormContentFilter extends OncePerRequestFilter,表单内容过滤器。
  • class RequestContextFilter extends OncePerRequestFilter,请求上下文过滤器。
  • class DelegatingFilterProxy extends GenericFilterBean,委派过滤器代理。
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws ServletException, IOException {Filter delegateToUse = this.delegate;if (delegateToUse == null) {synchronized(this.delegateMonitor) {delegateToUse = this.delegate;if (delegateToUse == null) {WebApplicationContext wac = this.findWebApplicationContext();if (wac == null) {throw new IllegalStateException("No WebApplicationContext found: no ContextLoaderListener or DispatcherServlet registered?");}delegateToUse = this.initDelegate(wac);}this.delegate = delegateToUse;}}this.invokeDelegate(delegateToUse, request, response, filterChain);}
 protected void invokeDelegate(Filter delegate, ServletRequest request, ServletResponse response, FilterChain filterChain) throws ServletException, IOException {delegate.doFilter(request, response, filterChain);}
  • class FilterChainProxy extends GenericFilterBean,过滤链代理。
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {boolean clearContext = request.getAttribute(FILTER_APPLIED) == null;if (!clearContext) {this.doFilterInternal(request, response, chain);} else {try {request.setAttribute(FILTER_APPLIED, Boolean.TRUE);this.doFilterInternal(request, response, chain);} catch (Exception var11) {Throwable[] causeChain = this.throwableAnalyzer.determineCauseChain(var11);Throwable requestRejectedException = this.throwableAnalyzer.getFirstThrowableOfType(RequestRejectedException.class, causeChain);if (!(requestRejectedException instanceof RequestRejectedException)) {throw var11;}this.requestRejectedHandler.handle((HttpServletRequest)request, (HttpServletResponse)response, (RequestRejectedException)requestRejectedException);} finally {SecurityContextHolder.clearContext();request.removeAttribute(FILTER_APPLIED);}}}
private void doFilterInternal(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {FirewalledRequest firewallRequest = this.firewall.getFirewalledRequest((HttpServletRequest)request);HttpServletResponse firewallResponse = this.firewall.getFirewalledResponse((HttpServletResponse)response);List<Filter> filters = this.getFilters((HttpServletRequest)firewallRequest);if (filters != null && filters.size() != 0) {if (logger.isDebugEnabled()) {logger.debug(LogMessage.of(() -> {return "Securing " + requestLine(firewallRequest);}));}FilterChainProxy.VirtualFilterChain virtualFilterChain = new FilterChainProxy.VirtualFilterChain(firewallRequest, chain, filters);virtualFilterChain.doFilter(firewallRequest, firewallResponse);} else {if (logger.isTraceEnabled()) {logger.trace(LogMessage.of(() -> {return "No security for " + requestLine(firewallRequest);}));}firewallRequest.reset();chain.doFilter(firewallRequest, firewallResponse);}}

final class VirtualFilterChain implements FilterChain(FilterChainProxy内)

private static final class VirtualFilterChain implements FilterChain {private final FilterChain originalChain;private final List<Filter> additionalFilters;private final FirewalledRequest firewalledRequest;private final int size;private int currentPosition;private VirtualFilterChain(FirewalledRequest firewalledRequest, FilterChain chain, List<Filter> additionalFilters) {this.currentPosition = 0;this.originalChain = chain;this.additionalFilters = additionalFilters;this.size = additionalFilters.size();this.firewalledRequest = firewalledRequest;}public void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException {if (this.currentPosition == this.size) {if (FilterChainProxy.logger.isDebugEnabled()) {FilterChainProxy.logger.debug(LogMessage.of(() -> {return "Secured " + FilterChainProxy.requestLine(this.firewalledRequest);}));}this.firewalledRequest.reset();this.originalChain.doFilter(request, response);} else {++this.currentPosition;Filter nextFilter = (Filter)this.additionalFilters.get(this.currentPosition - 1);if (FilterChainProxy.logger.isTraceEnabled()) {FilterChainProxy.logger.trace(LogMessage.format("Invoking %s (%d/%d)", nextFilter.getClass().getSimpleName(), this.currentPosition, this.size));}nextFilter.doFilter(request, response, this);}}}
  • class WebAsyncManagerIntegrationFilter extends OncePerRequestFilter,Web 异步管理器集成过滤器。
public final class WebAsyncManagerIntegrationFilter extends OncePerRequestFilter {private static final Object CALLABLE_INTERCEPTOR_KEY = new Object();public WebAsyncManagerIntegrationFilter() {}protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);SecurityContextCallableProcessingInterceptor securityProcessingInterceptor = (SecurityContextCallableProcessingInterceptor)asyncManager.getCallableInterceptor(CALLABLE_INTERCEPTOR_KEY);if (securityProcessingInterceptor == null) {asyncManager.registerCallableInterceptor(CALLABLE_INTERCEPTOR_KEY, new SecurityContextCallableProcessingInterceptor());}filterChain.doFilter(request, response);}
}
  • class SecurityContextPersistenceFilter extends GenericFilterBean,安全上下文持久性过滤器。
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {this.doFilter((HttpServletRequest)request, (HttpServletResponse)response, chain);}private void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {if (request.getAttribute("__spring_security_scpf_applied") != null) {chain.doFilter(request, response);} else {request.setAttribute("__spring_security_scpf_applied", Boolean.TRUE);if (this.forceEagerSessionCreation) {HttpSession session = request.getSession();if (this.logger.isDebugEnabled() && session.isNew()) {this.logger.debug(LogMessage.format("Created session %s eagerly", session.getId()));}}HttpRequestResponseHolder holder = new HttpRequestResponseHolder(request, response);SecurityContext contextBeforeChainExecution = this.repo.loadContext(holder);boolean var10 = false;try {var10 = true;SecurityContextHolder.setContext(contextBeforeChainExecution);if (contextBeforeChainExecution.getAuthentication() == null) {this.logger.debug("Set SecurityContextHolder to empty SecurityContext");} else if (this.logger.isDebugEnabled()) {this.logger.debug(LogMessage.format("Set SecurityContextHolder to %s", contextBeforeChainExecution));}chain.doFilter(holder.getRequest(), holder.getResponse());var10 = false;} finally {if (var10) {SecurityContext contextAfterChainExecution = SecurityContextHolder.getContext();SecurityContextHolder.clearContext();this.repo.saveContext(contextAfterChainExecution, holder.getRequest(), holder.getResponse());request.removeAttribute("__spring_security_scpf_applied");this.logger.debug("Cleared SecurityContextHolder to complete request");}}SecurityContext contextAfterChainExecution = SecurityContextHolder.getContext();SecurityContextHolder.clearContext();this.repo.saveContext(contextAfterChainExecution, holder.getRequest(), holder.getResponse());request.removeAttribute("__spring_security_scpf_applied");this.logger.debug("Cleared SecurityContextHolder to complete request");}}
  • class HeaderWriterFilter extends OncePerRequestFilter,标头编写器过滤器。
 protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {if (this.shouldWriteHeadersEagerly) {this.doHeadersBefore(request, response, filterChain);} else {this.doHeadersAfter(request, response, filterChain);}}private void doHeadersAfter(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws IOException, ServletException {HeaderWriterFilter.HeaderWriterResponse headerWriterResponse = new HeaderWriterFilter.HeaderWriterResponse(request, response);HeaderWriterFilter.HeaderWriterRequest headerWriterRequest = new HeaderWriterFilter.HeaderWriterRequest(request, headerWriterResponse);try {filterChain.doFilter(headerWriterRequest, headerWriterResponse);} finally {headerWriterResponse.writeHeaders();}}
  • class LogoutFilter extends GenericFilterBean,注销过滤器。
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {this.doFilter((HttpServletRequest)request, (HttpServletResponse)response, chain);}private void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {if (this.requiresLogout(request, response)) {Authentication auth = SecurityContextHolder.getContext().getAuthentication();if (this.logger.isDebugEnabled()) {this.logger.debug(LogMessage.format("Logging out [%s]", auth));}this.handler.logout(request, response, auth);this.logoutSuccessHandler.onLogoutSuccess(request, response, auth);} else {chain.doFilter(request, response);}}
  • abstract class AbstractAuthenticationProcessingFilter extends GenericFilterBeanimplements ApplicationEventPublisherAware, MessageSourceAware ,抽象认证处理过滤器。
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {this.doFilter((HttpServletRequest)request, (HttpServletResponse)response, chain);}private void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {if (!this.requiresAuthentication(request, response)) {chain.doFilter(request, response);} else {try {Authentication authenticationResult = this.attemptAuthentication(request, response);if (authenticationResult == null) {return;}this.sessionStrategy.onAuthentication(authenticationResult, request, response);if (this.continueChainBeforeSuccessfulAuthentication) {chain.doFilter(request, response);}this.successfulAuthentication(request, response, chain, authenticationResult);} catch (InternalAuthenticationServiceException var5) {this.logger.error("An internal error occurred while trying to authenticate the user.", var5);this.unsuccessfulAuthentication(request, response, var5);} catch (AuthenticationException var6) {this.unsuccessfulAuthentication(request, response, var6);}}}
  • class DefaultLoginPageGeneratingFilter extends GenericFilterBean,默认登录页面生成过滤器。
 public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {this.doFilter((HttpServletRequest)request, (HttpServletResponse)response, chain);}private void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {boolean loginError = this.isErrorPage(request);boolean logoutSuccess = this.isLogoutSuccess(request);if (!this.isLoginUrlRequest(request) && !loginError && !logoutSuccess) {chain.doFilter(request, response);} else {String loginPageHtml = this.generateLoginPageHtml(request, loginError, logoutSuccess);response.setContentType("text/html;charset=UTF-8");response.setContentLength(loginPageHtml.getBytes(StandardCharsets.UTF_8).length);response.getWriter().write(loginPageHtml);}}
  • class DefaultLogoutPageGeneratingFilter extends OncePerRequestFilter,默认注销页面生成过滤器。
  • class RequestCacheAwareFilter extends GenericFilterBean,请求缓存感知过滤器。
  • class SecurityContextHolderAwareRequestFilter extends GenericFilterBean,安全上下文持有者感知请求过滤器。
  • class AnonymousAuthenticationFilter extends GenericFilterBean implements InitializingBean,匿名身份验证过滤器。
  • class SessionManagementFilter extends GenericFilterBean,会话管理过滤器。
 public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {this.doFilter((HttpServletRequest)request, (HttpServletResponse)response, chain);}private void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {if (request.getAttribute("__spring_security_session_mgmt_filter_applied") != null) {chain.doFilter(request, response);} else {request.setAttribute("__spring_security_session_mgmt_filter_applied", Boolean.TRUE);if (!this.securityContextRepository.containsContext(request)) {Authentication authentication = SecurityContextHolder.getContext().getAuthentication();if (authentication != null && !this.trustResolver.isAnonymous(authentication)) {try {this.sessionAuthenticationStrategy.onAuthentication(authentication, request, response);} catch (SessionAuthenticationException var6) {this.logger.debug("SessionAuthenticationStrategy rejected the authentication object", var6);SecurityContextHolder.clearContext();this.failureHandler.onAuthenticationFailure(request, response, var6);return;}this.securityContextRepository.saveContext(SecurityContextHolder.getContext(), request, response);} else if (request.getRequestedSessionId() != null && !request.isRequestedSessionIdValid()) {if (this.logger.isDebugEnabled()) {this.logger.debug(LogMessage.format("Request requested invalid session id %s", request.getRequestedSessionId()));}if (this.invalidSessionStrategy != null) {this.invalidSessionStrategy.onInvalidSessionDetected(request, response);return;}}}chain.doFilter(request, response);}}
  • class ExceptionTranslationFilter extends GenericFilterBean implements MessageSourceAware,异常翻译过滤器。
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {this.doFilter((HttpServletRequest)request, (HttpServletResponse)response, chain);}private void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {try {chain.doFilter(request, response);} catch (IOException var7) {throw var7;} catch (Exception var8) {Throwable[] causeChain = this.throwableAnalyzer.determineCauseChain(var8);RuntimeException securityException = (AuthenticationException)this.throwableAnalyzer.getFirstThrowableOfType(AuthenticationException.class, causeChain);if (securityException == null) {securityException = (AccessDeniedException)this.throwableAnalyzer.getFirstThrowableOfType(AccessDeniedException.class, causeChain);}if (securityException == null) {this.rethrow(var8);}if (response.isCommitted()) {throw new ServletException("Unable to handle the Spring Security Exception because the response is already committed.", var8);}this.handleSpringSecurityException(request, response, chain, (RuntimeException)securityException);}}
  • class WsFilter extends GenericFilter ,ws过滤器。
  • class FilterSecurityInterceptor extends AbstractSecurityInterceptor implements Filter,过滤器安全拦截器。

FilterChain源码阅读相关推荐

  1. SpringMVC源码阅读:过滤器

    SpringMVC源码阅读:过滤器 目录 1.前言 2.源码分析 3.自定义过滤器 3.1 自定义过滤器继承OncePerRequestFilter 3.2 自定义过滤器实现Filter接口 4.过滤 ...

  2. Alibaba Druid 源码阅读(五)数据库连接池 连接关闭探索

    Alibaba Druid 源码阅读(五)数据库连接池 连接关闭探索 简介 在上文中探索了数据库连接池的获取,下面接着初步来探索下数据库连接的关闭,看看其中具体执行了那些操作 连接关闭 下面的具体的代 ...

  3. Alibaba Druid 源码阅读(四) 数据库连接池中连接获取探索

    Alibaba Druid 源码阅读(四) 数据库连接池中连接获取探索 简介 上文中分析了数据库连接池的初始化部分,接下来我们来看看获取连接部分的代码 数据库连接池中连接获取 下面的相关的代码,在代码 ...

  4. Alibaba Druid 源码阅读(二) 数据库连接池实现初步探索

    Alibaba Druid 源码阅读(二) 数据库连接池实现初步探索 简介 在上篇文章中,了解了连接池的应用场景和本地运行了示例,本篇文章中,我们尝试来探索下Alibaba Druid数据库连接池的整 ...

  5. 应用监控CAT之cat-client源码阅读(一)

    CAT 由大众点评开发的,基于 Java 的实时应用监控平台,包括实时应用监控,业务监控.对于及时发现线上问题非常有用.(不知道大家有没有在用) 应用自然是最初级的,用完之后,还想了解下其背后的原理, ...

  6. centos下将vim配置为强大的源码阅读器

    每日杂事缠身,让自己在不断得烦扰之后终于有了自己的清静时光来熟悉一下我的工具,每次熟悉源码都需要先在windows端改好,拖到linux端,再编译.出现问题,还得重新回到windows端,这个过程太耗 ...

  7. 源码阅读:AFNetworking(十六)——UIWebView+AFNetworking

    该文章阅读的AFNetworking的版本为3.2.0. 这个分类提供了对请求周期进行控制的方法,包括进度监控.成功和失败的回调. 1.接口文件 1.1.属性 /**网络会话管理者对象*/ @prop ...

  8. 源码阅读:SDWebImage(六)——SDWebImageCoderHelper

    该文章阅读的SDWebImage的版本为4.3.3. 这个类提供了四个方法,这四个方法可分为两类,一类是动图处理,一类是图像方向处理. 1.私有函数 先来看一下这个类里的两个函数 /**这个函数是计算 ...

  9. mybatis源码阅读

    说下mybatis执行一个sql语句的流程 执行语句,事务等SqlSession都交给了excutor,excutor又委托给statementHandler SimpleExecutor:每执行一次 ...

最新文章

  1. 大学计算机专业副修课,计算机学院举行本科课程教学大纲修订工作研讨会
  2. c语言两个程序合并一起运行,这两个程序如何可以在一起运行
  3. 微博客之后有可能是“切客”
  4. CSS仿艺龙首页鼠标移入图片放大
  5. androidtv item获取焦点设置动画和背景_动画技术的交互应用所作的动画
  6. C++对象数组与对象指针的用法【C++初学面向对象编程】
  7. c语言解析字符串报文,传递字符串数组报文和解析
  8. Hyperleger--共识算法 (2)
  9. python中字典dictionary详解及基本使用
  10. python --opencv图像处理Canny算子边缘检测(Roberts算子、Prewitt算子、Sobel算子、Laplacian算子、Scharr 算子、 LOG 算子)
  11. 帮助机器人自由行走 思岚科技推出激光导航模块
  12. 媒体查询之响应式布局
  13. 键盘 部分 按键 ~ 需要长按才能打出来
  14. CF1238E Keyboard Purchase
  15. PC 时代 Office 的仇,WPS 在 24 年后有机会报了
  16. 如何直观的理解机器学习PR曲线和ROC曲线?
  17. 游戏测试中容易被忽视的重点
  18. Leetcode-D35-数组-455. 分发饼干
  19. 在Node.js中使用express开启一个web服务器并定义简单中间件函数的使用
  20. 外星人计算机桌面,Alienware Alienware桌面Win10系统和BIOS设置教程

热门文章

  1. 什么是java环境变量_什么是java环境变量
  2. ASEMI整流桥DB107S参数,DB107S封装尺寸,DB107S图片
  3. ASEMI代理AD8638ARJZ-REEL7原装ADI车规级AD8638ARJZ-REEL7
  4. 科学计算机主板,一分钟带你了解家庭常见电脑故障问题(主板篇)
  5. Java static与final使用陷阱
  6. 用NERO复刻CD音乐
  7. map python函数_Python语言中map函数
  8. InternetOpen\InternetOpenUrl\InternetReadFile 等相关Win32 网络API 使用详细说明
  9. DevTools开发者工具(chrome谷歌浏览器)
  10. 全文检索知识库系统方案 (一)