spring-security源码-FilterChainProxy
1.Spring-Security系列导航2.spring-security使用-登录(一)3.spring-security使用-自定义数据源(二)4.spring-security使用-更友好的方式扩展登录AuthenticationProvider(三)5.spring-security使用-获得当前用户信息(四)6.spring-security使用-同一个账号只允许登录一次(五)7.spring-security使用-session共享(六)8.spring-security使用-安全防护HttpFirewall(七)9.spring-security使用-权限控制(八)10.spring-security源码-初始化(九)11.spring-security源码-如何初始化SecurityFilterChain到Servlet
12.spring-security源码-FilterChainProxy
13.spring-security源码-Filter之WebAsyncManagerIntegrationFilter(十)14.Spring-security源码-Filter之SecurityContextPersistenceFilter(十一)15.Spring-security源码-Filter之HeaderWriterFilter(十二)16.Spring-security源码-Filter之LogoutFilter(十三)17.Spring-security源码-Filter之UsernamePasswordAuthenticationFilter(十四)18.Spring-security源码-Filter之ConcurrentSessionFilter(十五)19.Spring-security源码-Filter之SessionManagementFilter(十六)20.Spring-security源码-Filter之RememberMeAuthenticationFilter(十七)21.Spring-security源码-Filter之ExceptionTranslationFilter(十八)22.Spring-security源码-Filter之FilterSecurityInterceptor(十九)23.Spring-security源码-注解权限原理(二十)24.Spring-security源码-注解权限原理之MethodSecurityInterceptor(二十一)25.Spring-Security基于源码扩展-一套系统多套登录逻辑(二十二)26.Spring-Security基于源码扩展-自定义登录(二十三)27.Spring-Security基于源码扩展-自定义认证失败返回(二十四)28.Spring-Security基于源码扩展-自定义授权注解(二十五)FilterChainProxy内部存储了我们各个HttpSecurty生成的SecurityFilterChain。FilterChainProxy实现了ServletFilter接口。只真正的入口
org.springframework.security.web.FilterChainProxy.doFilter
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); <1>执行 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); } } }
<1>
org.springframework.security.web.FilterChainProxy#doFilterInternal
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); <2>根据url获取filters 多登录逻辑实现 List<Filter> filters = this.getFilters((HttpServletRequest)firewallRequest); if (filters != null && filters.size() != 0) { if (logger.isDebugEnabled()) { logger.debug(LogMessage.of(() -> { return "Securing " + requestLine(firewallRequest); })); } VirtualFilterChain virtualFilterChain = new VirtualFilterChain(firewallRequest, chain, filters); //执行filter virtualFilterChain.doFilter(firewallRequest, firewallResponse); } else { if (logger.isTraceEnabled()) { logger.trace(LogMessage.of(() -> { return "No security for " + requestLine(firewallRequest); })); } firewallRequest.reset(); chain.doFilter(firewallRequest, firewallResponse); } }
<2>
org.springframework.security.web.FilterChainProxy#getFilters(javax.servlet.http.HttpServletRequest)
private List<Filter> getFilters(HttpServletRequest request) { int count = 0; Iterator var3 = this.filterChains.iterator(); SecurityFilterChain chain; do { if (!var3.hasNext()) { return null; } chain = (SecurityFilterChain)var3.next(); if (logger.isTraceEnabled()) { ++count; logger.trace(LogMessage.format("Trying to match request against %s (%d/%d)", chain, count, this.filterChains.size())); } } while(!chain.matches(request)); return chain.getFilters(); }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
2020-03-10 dubbo源码阅读-dubbo SPI实现原理(五)