Spring Security过滤器链的初始化(上)

149 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第9天,点击查看活动详情

Spring Security过滤器链的初始化

\quad众所周知,Spring Security的本质就是一系列的过滤器链,因为Spring Security中的所有功能都是由过滤器来实现的,这些不同的过滤器各司其职,组成一条完整的过滤器链。那么,这些过滤器链是如何加载的?那些Manager和Provider又是如何初始化的呢?先来看看Spring Security中一些比较重要的组件,这些是理解过滤器链的基础。

1. ObjectPostProcessor

\quad什么ObjectPostProcessor?它可以理解为对象后置处理器,也就是当一个对象创建成功后,如果还有一些额外的操作需要进行(也可能是某些专属的操作),那么可以通过ObjectPostProcessor来进行处理,所以它是Spring Security里非常常见的组件。这个接口中默认只有一个postProcess方法,就是对对象进行二次处理。因为ObjectPostProcessor是一个接口,所以要想知道他的具体逻辑还是得看它的实现类:

image.png

1.1AutowireBeanFactoryObjectPostProcessor

\quad因为Spring Security中大量采用了Java 配置,许多过滤器都是通过构造器new出来的,但是这些直接new出来的对象并不会自动注入到Spring容器中,这也就产生了问题,大量的过滤器对象需要我们手动注入到到Spring 容器中,为了解决这一问题,就有了AutowireBeanFactoryObjectPostProcessor对象,他的工作就是将这些对象成功注入到Spring容器中,它的实现原理就是通过调用Spring 容器中的AutowireCapableBeanFactory对象,然后将一个个new出来的对象注入到Spring 容器中去。
CompositeObjectPostProcessor:这是ObjectPostProcessor的另一个实现,一个对象可以有 一个后置处理器,开发者也可以自定义多个对象后置处理器。

1.2 CompositeObjectPostProcessor

\quadCompositeObjectPostProcessor是一个组合的对象后置处理器,它里边维护了一个List集合,所以集合中存放的就是针对某一个对象的全部置处理器,当需要执行对象的后置处理器时,会遍历集合中的所有实例,分别调用实例的postProcess方法进行对象后置处理。在Spring Security 框架中,最终使用的对象后置处理器其实就是CompositeObjectPostProcessor,它里边的集合默认只有一个对象,自然就是AutowireBeanFactoryObjectPostProcessor了。

2. SecurityFilterChain

\quad顾名思义,SecurityFilterChain 就是Spring Security 中的过滤器链对象。该接口包含两个方法:

  • matches:该方法用来判断request请求是否应该被当前过滤器链所处理。
  • getFilters: 该方法返回一个List集合,集合中存放的就是Spring Security 中的过滤器。换言之,如果matches方法返回true,那么request请求就会在getFiters方法所返回的Filter集合中被处理。 如果想要了解SecurityFilterChain的具体功能,还是得看其具体的实现类,而它的实现类只有一个,也就是默认的实现类----DefaultSecurityFilterChain, 其中定义了两个属性,并具体实现了SecurityFilterChain 中的两个方法:
public final class DefaultSecurityFilterChain implements SecurityFilterChain {

   private static final Log logger = LogFactory.getLog(DefaultSecurityFilterChain.class);

   private final RequestMatcher requestMatcher;

   private final List<Filter> filters;

   public DefaultSecurityFilterChain(RequestMatcher requestMatcher, Filter... filters) {
      this(requestMatcher, Arrays.asList(filters));
   }

   public DefaultSecurityFilterChain(RequestMatcher requestMatcher, List<Filter> filters) {
      if (filters.isEmpty()) {
         logger.info(LogMessage.format("Will not secure %s", requestMatcher));
      }
      else {
         logger.info(LogMessage.format("Will secure %s with %s", requestMatcher, filters));
      }
      this.requestMatcher = requestMatcher;
      this.filters = new ArrayList<>(filters);
   }

   public RequestMatcher getRequestMatcher() {
      return this.requestMatcher;
   }

   @Override
   public List<Filter> getFilters() {
      return this.filters;
   }

   @Override
   public boolean matches(HttpServletRequest request) {
      return this.requestMatcher.matches(request);
   }

   @Override
   public String toString() {
      return this.getClass().getSimpleName() + " [RequestMatcher=" + this.requestMatcher + ", Filters=" + this.filters
            + "]";
   }

}

\quad从代码可以看出,在DefaultSecurityFilterChain的构造方法中,需要传入两个对象,一个是请求 匹配器requestMatcher,而另一个则是可变参数,可以传入过滤器集合或者过滤器数组。

\quad下篇文章会具体介绍一下SecurityBuilder接口,及其常见的实现类。