SpringSecurity之基本原理——过滤器加载过程

倪大野

共 14129字,需浏览 29分钟

 ·

2023-05-08 08:46

点击上方“蓝字”,发现更多精彩。

76775d4b472e87bda48bed07bd264d23.webp

前一篇讲解了S p r i n g S e c u r i t y的过滤器链的基本只是,今天我们就要进入过滤器,看看其加载过程是如何的?


相信认真度过第一篇文章的小伙伴还记得,我说在S p r i n g B o o t出现后,帮助我们省去了那些繁琐的配置,实现了自动配置。那么,我们更应该了解他是如何实现自动加载的了!




0 1 过滤器如何进行加载

要是用过滤器,就必须配置过滤器 DelegatingFilterProxy ,之所以我们在前面的示例中没有进行配置,是因为Spring Boot 为我们完成了。

具体的加载逻辑如下图所示:

b1076bbfa5ac169aa2638f32b0068b96.webp

0 2 代码实现

首先进入到DelegatingFilterProxy类中的d o F i l t e r中

                
                  
                    
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws ServletException, IOException {
Filter delegateToUse = this.delegate;
if (delegateToUse == null) {
Object var5 = this.delegateMonitor;
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, f i l t e r C h a i n);
}


执行delegateToUse = this.initDelegate(wac);后进入到F i l t e r C h a i n P r o x y 类中,


List<Filter> filters = this.getFilters((HttpServletRequest)firewallRequest);加载所有的过滤器
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);
}
}


往期 精彩 回顾



开篇点睛——Elasticsearch 工欲善其事必先利其器——Elasticsearch安装 如何将网站全部变成灰色的素装效果,瞧过来 宇讯代码生成器开源了 微信支付系列之——统一下单 springboot自动装配原理 如何优雅的实现接口防刷 系统日志规范
浏览 51
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报