ToB企服应用市场:ToB评测及商务社交产业平台

标题: Spring Security过滤器链分析-初始化流程(8) [打印本页]

作者: 守听    时间: 2022-9-16 17:13
标题: Spring Security过滤器链分析-初始化流程(8)
过滤器链分析

  提起Spring Security的实现原理,很多读者都会想到过滤器链。因为Spring Security中的所有功能都是通过过滤器来实现的,这些过滤器组成一个完整的过滤器链。那么,这些过滤器 链是如何初始化的?我们前面反复提到的AuthenticationManager又是如何初始化的?通过前面章节的学习,相信读者己经有了一些认识,本章我们将从头开始,分析Spring Security的初始化流程,同时再通过六个案例来让读者深入理解并且学会如何制作过滤器链。由于初始化流程相对复杂,因此我们没有选择在一开始就讲解Spring Security初始化流程,而是放到本节。当读者对于Spring Security有一个基本的认知之后再来讲解,此时相对来说就会比较容易理解。
本章涉及的主要知识点有:
1. 初始化流程分析

  Spring Security初始化流程整体上来说理解起来并不难,但是这里涉及许多零碎的知识点, 把这些零碎的知识点搞懂了,再来梳理初始化流程就会容易很多。因此,这里先介绍一下SpringSecurity中一些常见的关键组件,在理解这些组件的基础上,再来分析初始化流程,就能加深对其的理解。
  1.1 ObjectPostProcessor  

  ObjectPostProcessor是Spring Security中使用频率最高的组件之一,它是一个对象后置处理器,也就是当一个对象创建成功后,如果还有一些额外的事情需要补充,那么可以通过 ObjectPostProcessor来进行处理。这个接口中默认只有一个方法postProcess,该方法用来完成对对象的二次处理,代码如下:
  1. public interface ObjectPostProcessor<T> {
  2.         <O extends T> O postProcess(O object);
  3. }
复制代码
  ObjectPostProcessor默认有两个继承类,如图4-1所示。
  
图 4-1
  在Spring Security中,开发者可以灵活地配置项目中需要哪些Spring Security过滤器,一 旦选定过滤器之后,每一个过滤器都会有一个对应的配置器,叫作xxxConfigurer (例如CorsConfigurer. CsrfConfigurer等),过滤器都是在 xxxConfigurer 中 new 出来的,然后在 postProcess方法中处理一遍,就将这些过滤器注入到Spring容器中了。这是对象后置处理器ObjectPostProcessor的主要作用。
  1.2 SecurityFilterChain

  从名称上可以看出,SecurityFilterChain就是Spring Security中的过滤器链对象。下面来看一下 SecurityFilterChain的源码:
  1. public interface SecurityFilterChain {
  2.         boolean matches(HttpServletRequest request);
  3.         List<Filter> getFilters();
  4. }
复制代码
可以看到,SecurityFilterChain中有两个方法:
SecurityFilterChain只有一个默认的实现类就是DefaultSecurityFilterChain,其中定义了两 个属性,并具体实现了 SecurityFilterChain中的两个方法:
查看代码
  1.  public final class DefaultSecurityFilterChain implements SecurityFilterChain {
  2.         private static final Log logger = LogFactory.getLog(DefaultSecurityFilterChain.class);
  3.         private final RequestMatcher requestMatcher;
  4.         private final List<Filter> filters;
  5.         public DefaultSecurityFilterChain(RequestMatcher requestMatcher, Filter... filters) {
  6.                 this(requestMatcher, Arrays.asList(filters));
  7.         }
  8.         public DefaultSecurityFilterChain(RequestMatcher requestMatcher, List<Filter> filters) {
  9.                 logger.info("Creating filter chain: " + requestMatcher + ", " + filters);
  10.                 this.requestMatcher = requestMatcher;
  11.                 this.filters = new ArrayList<>(filters);
  12.         }
  13.         public RequestMatcher getRequestMatcher() {
  14.                 return requestMatcher;
  15.         }
  16.         public List<Filter> getFilters() {
  17.                 return filters;
  18.         }
  19.         public boolean matches(HttpServletRequest request) {
  20.                 return requestMatcher.matches(request);
  21.         }
  22.         @Override
  23.         public String toString() {
  24.                 return "[ " + requestMatcher + ", " + filters + "]";
  25.         }
  26. }
复制代码
  可以看到,在DefaultSecurityFilterChain的构造方法中,需要传入两个对象,一个是请求 匹配器requestMatcher,另一个则是过滤器集合或者过滤器数组filters。这个实现类比较简单, 这里就不再赘述了。
  需要注意的是,在一个Spring Security项目中,SecurityFilterChain的实例可能会有多个,在后面的小节中会详细分析,并演示多个SecurityFilterChain实例的情况。
  1.3 SecurityBuilder

  Spring Security中所有需要构建的对象都可以通过SecurityBuilder来实现,默认的过滤器 链、代理过滤器AuthenticationManager 等,都可以通过 SecurityBuilder来构建。SecurityBuilder的实现类如图4-2所示。
  
图 4-2
  SecurityBuilder:
  我们先来看SecurityBuilder的源码:
  1. public interface SecurityBuilder<O> {
  2.         O build() throws Exception;
  3. }
复制代码
  由上述代码可以看到,SecurityBuilder中只有一个build方法,就是对象构建方法。build 方法的返回值,就是具体构建的对象泛型O,也就是说不同的SecurityBuilder将来会构建出不同的对象。
  HttpSecurityBuiIder:
  HttpSecurityBuilder是用来构建 HttpSecurity对象的,HttpSecurityBuilder 的定义如下:
[code]public interface HttpSecurityBuilder extends                SecurityBuilder {         C getConfigurer(                        Class clazz);             C removeConfigurer(                        Class clazz);             void setSharedObject(Class sharedType, C object);             C getSharedObject(Class sharedType);            H authenticationProvider(AuthenticationProvider authenticationProvider);            H userDetailsService(UserDetailsService userDetailsService) throws Exception;            H addFilterAfter(Filter filter, Class




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4