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

标签: java | 发表时间:2020-07-06 11:16 | 作者:码农小胖哥
出处:https://segmentfault.com/blogs

1. 前言

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

2. Servlet Filter体系

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

servlet过滤器链

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体系中,类图如下:

image-20200701162747774

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

4. DelegatingFilterProxy

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

DelegatingFilterProxy

5. SecurityFilterChain

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

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

SecurityFilterChain

6. FilterChainProxy

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

不同的请求经过不同的SecurityFilterChain

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

扩展阅读: Spring Security 过滤器链

7. 总结

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

Spring Security Servlet过滤器链组织关系

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

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

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

相关 [spring security 干货] 推荐:

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

- - SegmentFault 最新的文章
我在 Spring Security 实战干货:内置 Filter 全解析对 Spring Security的内置过滤器进行了罗列,但是 Spring Security真正的过滤器体系才是我们了解它是如何进行"认证"、“授权”、“防止利用漏洞”的关键. Servlet Filter体系. 这里我们以 Servlet Web为讨论目标, Reactive Web暂不讨论.

Spring security oauth2最简单入门环境搭建--二、干货

- - ITeye博客
关于OAuth2的一些简介,见我的上篇blog: http://wwwcomy.iteye.com/blog/2229889 PS:貌似内容太水直接被鹳狸猿干沉. 友情提示 学习曲线:spring+spring mvc+spring security+Oauth2基本姿势,如果前面都没看过请及时关闭本网页.

cxf + spring 的WS Security示例

- - RSS - IT博客云
WSPasswordCallback的 passwordType属性和 password属性都为null,你只能获得用户名(identifier),一般这里的逻辑是使用这个用户名到数据库中查询其密码,然后再设置到 password属性,WSS4J会自动比较客户端传来的值和你设置的这个值. 你可能会问为什么这里CXF不把客户端提交的密码传入让我们在 ServerPasswordCallbackHandler中比较呢.

Spring Boot 使用Spring security 集成CAS - CSDN博客

- -
      创建Maven工程:springboot-security-cas.       创建工程后,打开pom.xml,在pom.xml中加入以下内容:.           .           . 3.创建application.properties.

奔的家园 | CAS 与 Spring Security 3.1整合配置详解

- - Delicious/searchfull
该方式通过获取CAS系统里的角色,来支持CAS与Spring Security的关联,注意该文章authorities部分. 一般来说,Web 应用的安全性包括用户认证(Authentication)和用户授权(Authorization)两个部分. 用户认证指的是验证某个用户是否为系统中的合法主体,也就是说用户能否访问该系统.

spring security 3.1.0 控制用户重复登陆

- - CSDN博客架构设计推荐文章
通过配置我们可以实现两个需求 1、限制不允许第二个用户登录,2、第二个登陆用户踢掉前一个登陆用户 . 假设你的spring架构已经可以使用了(其他的主要功能完成),需要增加登录限制功能. 注:这里只写配置不写原理(不懂的就问度娘),其实个人认为先配置好跑起来再研究下原理最好了. 通过sessionRegistry可以获取系统当前在线人数和登录用户信息.

spring security 3中推荐使用BCrypt算法加密密码

- - jackyrong
spring security 3中推荐使用BCrypt算法加密密码了,以前使用的是md5,. Md5PasswordEncoder 和 ShaPasswordEncoder,现在不推荐了,推荐用bcrpt. Bcrpt中的salt可以是随机的,比如:.   其中strenth为长度. 已有 0 人发表留言,猛击->> 这里<<-参与讨论.

Spring Security判断用户是否已经登录 - 简书

- -
方法一、JSP中检查user principal. 需要:.

盘点 Spring Security 框架中的八大经典设计模式

- - SegmentFault 最新的文章
上次有小伙伴建议,源码分析太枯燥了,要是能够结合设计模式一起来,这样更有助于大家理解 Spring Security 源码,同时还能复习一波设计模式. 因此松哥今天就试着整一篇,和大家来聊一聊 Spring Security 中涉及到的设计模式,不过 Spring Security 中涉及到的设计模式还是非常多的,松哥这里讲几个,剩下的欢迎小伙伴们留言补充.

Spring Security中用JWT退出登录时很容易犯的错

- - 程序猿DD
最近有个粉丝提了个问题,说他在Spring Security中用JWT做退出登录的时无法获取当前用户,导致无法证明“我就是要退出的那个我”,业务失败. 经过我一番排查找到了原因,而且这个错误包括我自己的大部分人都犯过. 之所以要说Session会话,是因为Spring Security默认配置就是有会话的,所以当你登录以后Session就会由服务端保持直到你退出登录.