持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第9天,点击查看活动详情
Spring Security过滤器链的初始化
众所周知,Spring Security的本质就是一系列的过滤器链,因为Spring Security中的所有功能都是由过滤器来实现的,这些不同的过滤器各司其职,组成一条完整的过滤器链。那么,这些过滤器链是如何加载的?那些Manager和Provider又是如何初始化的呢?先来看看Spring Security中一些比较重要的组件,这些是理解过滤器链的基础。
1. ObjectPostProcessor
什么ObjectPostProcessor?它可以理解为对象后置处理器,也就是当一个对象创建成功后,如果还有一些额外的操作需要进行(也可能是某些专属的操作),那么可以通过ObjectPostProcessor来进行处理,所以它是Spring Security里非常常见的组件。这个接口中默认只有一个postProcess方法,就是对对象进行二次处理。因为ObjectPostProcessor是一个接口,所以要想知道他的具体逻辑还是得看它的实现类:
1.1AutowireBeanFactoryObjectPostProcessor
因为Spring Security中大量采用了Java 配置,许多过滤器都是通过构造器new出来的,但是这些直接new出来的对象并不会自动注入到Spring容器中,这也就产生了问题,大量的过滤器对象需要我们手动注入到到Spring 容器中,为了解决这一问题,就有了AutowireBeanFactoryObjectPostProcessor对象,他的工作就是将这些对象成功注入到Spring容器中,它的实现原理就是通过调用Spring 容器中的AutowireCapableBeanFactory对象,然后将一个个new出来的对象注入到Spring 容器中去。
CompositeObjectPostProcessor:这是ObjectPostProcessor的另一个实现,一个对象可以有
一个后置处理器,开发者也可以自定义多个对象后置处理器。
1.2 CompositeObjectPostProcessor
CompositeObjectPostProcessor是一个组合的对象后置处理器,它里边维护了一个List集合,所以集合中存放的就是针对某一个对象的全部置处理器,当需要执行对象的后置处理器时,会遍历集合中的所有实例,分别调用实例的postProcess方法进行对象后置处理。在Spring Security 框架中,最终使用的对象后置处理器其实就是CompositeObjectPostProcessor,它里边的集合默认只有一个对象,自然就是AutowireBeanFactoryObjectPostProcessor了。
2. SecurityFilterChain
顾名思义,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
+ "]";
}
}
从代码可以看出,在DefaultSecurityFilterChain的构造方法中,需要传入两个对象,一个是请求 匹配器requestMatcher,而另一个则是可变参数,可以传入过滤器集合或者过滤器数组。
下篇文章会具体介绍一下SecurityBuilder接口,及其常见的实现类。