30

Spring Security 实战干货:图解Spring Security中的Servlet过滤器体系

 4 years ago
source link: https://segmentfault.com/a/1190000023102733
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

1. 前言

我在 Spring Security 实战干货:内置 Filter 全解析Spring Security 的内置过滤器进行了罗列,但是 Spring Security 真正的过滤器体系才是我们了解它是如何进行"认证"、“授权”、“防止利用漏洞”的关键。

2. Servlet Filter体系

这里我们以 Servlet Web 为讨论目标, Reactive Web 暂不讨论。我们先来看下最基础的 Servlet 体系,在 Servlet 体系中客户端发起一个请求过程是经过0到N个 Filter 然后交给 Servlet 处理。

AZvMvij.png!web

Filter 不但可以修改 HttpServletRequestHttpServletResponse ,可以让我们在请求响应的前后做一些事情,甚至可以终止过滤器链 FilterChain 的传递。

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
     //  请求被servlet 处理前  
      if(condition){
        // 根据条件来进入下一个过滤器
          chain.doFilter(request, response);  
      }
     // 请求被执行完毕后处理一些事情  
 }

由于 Filter 仅影响下游 FiltersServlet ,因此每个 Filter 调用的顺序非常重要。 Spring Security 正是根据这个个特性来实现一系列的安全功能。接下来我们来看看它们是如何结合的。

3. GenericFilterBean

在该系列的文章开篇我对 Spring Security和Shiro进行了简单的对比Spring Security 利用了 Spring IOCAOP 的特性而无法脱离 Spring 独立存在,而 Apache Shiro 可以独立存在。所以今天我们要一探究竟,看看他们是如何结合的。

Spring结合 Servlet Filter 自然是要为 Servlet Filter 注入 Spring Bean 的特性,所以就搞出了一个抽象 Filter Bean ,这个抽象过滤器 GenericFilterBean 并不是在 Spring Security 下,而是 Spring Web 体系中,类图如下:

zInAba2.png!web

从类图上看 Filter 接口已经被注入了多个 Spring Bean 的特性,纳入了 Spring Bean 生命周期,使得 Spring IoC 容器能够充分的管理 Filter

4. DelegatingFilterProxy

我们希望 Servlet 能够按照它自己的标准来注册到过滤器链中工作,但是同时也希望它能够被 Spring IoC 管理,所以Spring提供了一个 GenericFilterBean 的实现 DelegatingFilterProxy 。我们可以将原生的 Servlet Filter 或者 Spring Bean Filter 委托给 DelegatingFilterProxy ,然后在结合到 Servlet FilterChain 中。

JbQvMnI.png!web

5. SecurityFilterChain

针对不同符合 Ant Pattern 的请求可能会走不同的过滤器链,比如登录会去验证,然后返回登录结果;管理后台的接口走后台的安全逻辑,应用客户端的接口走客户端的安全逻辑。 Spring Security 提供了一个 SecurityFilterChain 接口来满足被匹配 HttpServletRequest 走特定的过滤器链的需求。

public interface SecurityFilterChain {
    // 判断请求 是否符合该过滤器链的要求
   boolean matches(HttpServletRequest request);
    // 对应的过滤器链
   List<Filter> getFilters();
}

biABzee.png!web

6. FilterChainProxy

不同的 SecurityFilterChain 应该是互斥而且平等的,它们之间不应该是上下游关系。

BNjmYfV.png!web

如上图请求被匹配到不同的 SecurityFilterChain 然后在执行剩余的过滤器链。它们经过 SecurityFilterChain 的总流程是相似的,而且有些时候特定的一些 SecurityFilterChain 也需要被集中管理来实现特定一揽子的请求的过滤逻辑。所以就有了另外一个 GenericFilterBean 实现来做这个事情,它就是 FilterChainProxy 。它的作用就是拦截符合条件的请求,然后根据请求筛选出符合要求的 SecurityFilterChain ,然后链式的执行这些 Filter ,最后继续执行剩下的 FilterChain

扩展阅读: Spring Security 过滤器链

7. 总结

结合上面,最终上述这些概念的关系彻底搞清楚了,搞清楚过滤器的运作模式对于学习和使用 Spring Security 至关重要。

EriEV3J.png!web

多多关注微信公众号: 码农小胖哥 获取更多的技术干货。六月打榜结果已出请中奖的同学速度联系我领取,另外七月打榜前三会送上热门技术正版实体书籍, 打榜的要求只有一个关注、转发、再看、点赞都可以增加自己的排名。

关注公众号:Felordcn 获取更多资讯

个人博客:https://felord.cn


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK