Filter链相关接口
SpringSecurity简单理解,就是将一堆Filter通过SecurityFilterChain有效的组织起来,并通过代理的方式放到Spring中执行
SecurityFilterChain
表示在对需要处理的URL匹配时获取在该URL中对于的Filter
列表
public interface SecurityFilterChain {
// 当前FilterChain是否为需要执行filterchain处理的请求
boolean matches(HttpServletRequest request);
// matches匹配上后,对应的Filter链
List<Filter> getFilters();
}
FilterChainProxy
对应有多个SecurityFilterChain
,该类只是一个代理类,代理N个请求的处理链,
其中getFilters
根据匹配规则找到第一个匹配的SecurityFilterChain
并通过VirtualFilterChain
执行执行SecurityFilterChain
中的filter
方法
真正执行的入口在doFilterInternal
方法中,执行
private void doFilterInternal(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
List<Filter> filters = getFilters(fwRequest);
VirtualFilterChain vfc = new VirtualFilterChain(fwRequest, chain, filters);
vfc.doFilter(fwRequest, fwResponse);
}
找到请求执行的SecurityFilterChain
private List<Filter> getFilters(HttpServletRequest request) {
for (SecurityFilterChain chain : filterChains) {
if (chain.matches(request)) {
return chain.getFilters(); //返回的实际是SecurityFilterChain下的所有filter
}
}
return null;
}
对匹配上的FilterChain
按顺序执行Filter
// 内部类VirtualFilterChain
public void doFilter(ServletRequest request, ServletResponse response)
throws IOException, ServletException {
if (currentPosition == size) {
// 执行ServletFilter,走下一个filter执行
originalChain.doFilter(request, response);
} else {
currentPosition++;
Filter nextFilter = additionalFilters.get(currentPosition - 1);
nextFilter.doFilter(request, response, this);
}
}
}
可以看到FilterChainProxy
是执行请求处理的核心,该类是如何创建的后面单点
DelegatingFilterProxy
作为Spring Security
处理的入口
类中的一个属性targetBeanName
表示在IOC容器中的FilterChainProxy
bean的名字,默认有两个
-
SessionRepositoryFilter
名字 -
SpringSecurityFilterChain
可以看到启动时拿到的就是
那么这些Filter
是如何,有效的组织起来的呢?
实际上,就是使用构建者模式,通过WebSecurity
,HttpSecurity
这两个Builder构造出来的
SecurityFilterChain的构造
HttpSecurity
构造出DefaultSecurityFilterChain
,该DefaultSecurityFilterChain
是一个默认实现
观测HttpSecurity
可以发现SecurityBuilder
接口定义出构建的成果是啥,AbstractConfiguredSecurityBuilder
–>AbstractSecurityBuilder
–>SecurityBuilder
public final class HttpSecurity extends
AbstractConfiguredSecurityBuilder<DefaultSecurityFilterChain, HttpSecurity>
implements SecurityBuilder<DefaultSecurityFilterChain>,
HttpSecurityBuilder<HttpSecurity> {
}
//该类需要在Configurer的帮助下构建
public abstract class AbstractConfiguredSecurityBuilder<O, B extends SecurityBuilder<O>>
extends AbstractSecurityBuilder<O> {
@Override
protected final O doBuild() throws Exception {
synchronized (configurers) {
buildState = BuildState.INITIALIZING;
beforeInit();
init();
buildState = BuildState.CONFIGURING;
beforeConfigure();
configure(); //将所有的configurer应用到当前builder上,
buildState = BuildState.BUILDING;
O result = performBuild();
buildState = BuildState.BUILT;
return result;
}
}
}
//保证builder只初识化一次
public abstract class AbstractSecurityBuilder<O> implements SecurityBuilder<O> {
private AtomicBoolean building = new AtomicBoolean();
private O object;
public final O build() throws Exception {
if (this.building.compareAndSet(false, true)) {
this.object = doBuild();
return this.object;
}
throw new AlreadyBuiltException("This object has already been built");
}
public final O getObject() {
if (!this.building.get()) {
throw new IllegalStateException("This object has not been built");
}
return this.object;
}
//真正执行build的地方,模板方法模式
protected abstract O doBuild() throws Exception;
}
//SecurityBuilder
public interface SecurityBuilder<O> {
O build() throws Exception;
}
简单理解就是SecurityBuilder
在配置器SecurityConfigurer
的帮助下,完成SecurityFitlerChain
的构建
FilterChainProxy的构造
FilterChainProxy是通过
WebSecurity`构造出来的
public final class WebSecurity extends
AbstractConfiguredSecurityBuilder<Filter, WebSecurity> implements
SecurityBuilder<Filter>, ApplicationContextAware {
// 持有所有的FilterChain
private final List<SecurityBuilder<? extends SecurityFilterChain>> securityFilterChainBuilders = new ArrayList<SecurityBuilder<? extends SecurityFilterChain>>();
//将所有的FilterChain通过FilterChainProxy组织起来
protected Filter performBuild() throws Exception {
int chainSize = ignoredRequests.size() + securityFilterChainBuilders.size();
List<SecurityFilterChain> securityFilterChains = new ArrayList<SecurityFilterChain>(
chainSize);
for (RequestMatcher ignoredRequest : ignoredRequests) {
securityFilterChains.add(new DefaultSecurityFilterChain(ignoredRequest));
}
for (SecurityBuilder<? extends SecurityFilterChain> securityFilterChainBuilder : securityFilterChainBuilders) {
securityFilterChains.add(securityFilterChainBuilder.build());
}
FilterChainProxy filterChainProxy = new FilterChainProxy(securityFilterChains);
if (httpFirewall != null) {
filterChainProxy.setFirewall(httpFirewall);
}
filterChainProxy.afterPropertiesSet();
Filter result = filterChainProxy;
}
postBuildAction.run();
return result;
}
本节只是简单讲了Spring Filter是如何组织起来,处理请求的,接下来聊聊具体到1个Filter中的关键点