Spring Security中的所有功能都是通过过滤器来实现的,这些过滤器组成一个完整的过滤器链。过滤器链涉及很多基础组件,首先梳理一下这些关键组件,会方便理解Spring Security过滤器链。
他是一个对象后置处理器,当一个对象创建成功后,如果需要一些额外的事情需要补充,就可以通过ObjectPostProcessor来进行处理。
在Spring Security中,开发者可以灵活的配置项目中需要哪些过滤器,一旦选定过滤器之后,每个过滤器会有一个对应的配置器,叫做xxxConfigurer(例如CorsConfigurer),过滤器都是在xxxConfigurer中new出来的,然后再postProcess方法中处理一遍,就将这些过滤器注入到Spring容器中了。
- public interface ObjectPostProcessor
{ -
extends T> O postProcess(O object); - }
默认有两个继承类,继承关系如下

当一个对象被new出来以后,只要调用AutowireBeanFactoryObjectPostProcessor#postProcess方法,就可以成功注入到Spring容器中。
- @Override
- @SuppressWarnings("unchecked")
- public
T postProcess(T object) { - if (object == null) {
- return null;
- }
- T result = null;
- try {
- result = (T) this.autowireBeanFactory.initializeBean(object, object.toString());
- }
- catch (RuntimeException ex) {
- Class> type = object.getClass();
- throw new RuntimeException("Could not postProcess " + object + " of type " + type, ex);
- }
- this.autowireBeanFactory.autowireBean(object);
- if (result instanceof DisposableBean) {
- this.disposableBeans.add((DisposableBean) result);
- }
- if (result instanceof SmartInitializingSingleton) {
- this.smartSingletons.add((SmartInitializingSingleton) result);
- }
- return result;
- }
他是一个组合的对象后置处理器,维护了一个List集合,存放了所有的后置处理器。在Spring Security框架中,最终使用的对象后置处理器其实就是CompositeObjectPostProcessor,他里面的集合默认只有一个对象,就是AutowireBeanFactoryObjectPostProcessor。
- private static final class CompositeObjectPostProcessor implements ObjectPostProcessor
-
- private List
> postProcessors = new ArrayList<>(); -
- @Override
- @SuppressWarnings({ "rawtypes", "unchecked" })
- public Object postProcess(Object object) {
- for (ObjectPostProcessor opp : this.postProcessors) {
- Class> oppClass = opp.getClass();
- Class> oppType = GenericTypeResolver.resolveTypeArgument(oppClass, ObjectPostProcessor.class);
- if (oppType == null || oppType.isAssignableFrom(object.getClass())) {
- object = opp.postProcess(object);
- }
- }
- return object;
- }
-
- }
SecurityFilterChain是Spring Security中的过滤器链对象
- public interface SecurityFilterChain {
-
- //用来判断request请求是否应该被当前过滤器链处理
- boolean matches(HttpServletRequest request);
-
- //如果matches返回true,那么request请求就会在getFilters方法返回的Filter集合中被处理
- List
getFilters(); -
- }
他的默认实现类是DefaultSecurityFilterChain,需要注意的点是,在一个Spring Security项目中,SecurityFilterChain实例可能有多个。
- //省略部分代码
- public final class DefaultSecurityFilterChain implements SecurityFilterChain {
-
- private final RequestMatcher requestMatcher;
-
- private final List
filters; -
- @Override
- public List
getFilters() { - return this.filters;
- }
-
- @Override
- public boolean matches(HttpServletRequest request) {
- return this.requestMatcher.matches(request);
- }
-
- }

Spring Security中很多对象都可以通过SecurityBuilder来构建,源码如下:
- public interface SecurityBuilder
{ - O build() throws Exception;
- }
用来构建HttpSecurity对象,最终构建出来的对象为DefaultSecurityFilterChain,默认构建后的filter顺序如下:

HttpSecurityBuilder源码如下:
- //HttpSecurityBuilder默认实现类只有HttpSecurity,可以把H当作HttpSecurity
- public interface HttpSecurityBuilder
extends HttpSecurityBuilder> extends SecurityBuilder { -
-
extends SecurityConfigurer> C getConfigurer(Class clazz) ; -
-
extends SecurityConfigurer> C removeConfigurer(Class clazz) ; -
- //设置可以在多个配置器之间共享的对象
-
void setSharedObject(Class sharedType, C object) ; -
-
C getSharedObject(Class sharedType) ; -
- //配置认证器AuthenticationProvider
- H authenticationProvider(AuthenticationProvider authenticationProvider);
-
- //配置数据源
- H userDetailsService(UserDetailsService userDetailsService) throws Exception;
-
- H addFilterAfter(Filter filter, Class extends Filter> afterFilter);
-
- H addFilterBefore(Filter filter, Class extends Filter> beforeFilter);
-
- //这个过滤器必须是Spring Security框架提供的过滤器的实例或者扩展,添加完成后,会自动进行排序
- H addFilter(Filter filter);
- }
AbstractSecurityBuilder实现了SecurityBuilder接口,并对build做了完善,确保只build一次。
- public abstract class AbstractSecurityBuilder
implements SecurityBuilder { -
- private AtomicBoolean building = new AtomicBoolean();
-
- private O object;
-
- //设置为final,确保子类不会再重写这个方法
- @Override
- 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;
- }
-
- protected abstract O doBuild() throws Exception;
-
- }
它允许securityconfigururer被应用到它。这使得修改SecurityBuilder成为一种策略,它可以被自定义,并分解成许多securityconfigururer对象,这些对象比SecurityBuilder有更具体的目标。
例如,一个SecurityBuilder可以构建一个DelegatingFilterProxy,但是一个securityconfiger可以用会话管理、基于表单的登录、授权等所需的过滤器填充SecurityBuilder。
在这个类中有一个声明了一个枚举,用来描述构建过程的不同状态。
- private static enum BuildState {
- UNBUILT(0),
- INITIALIZING(1),
- CONFIGURING(2),
- BUILDING(3),
- BUILT(4);
-
- private final int order;
-
- private BuildState(int order) {
- this.order = order;
- }
-
- public boolean isInitializing() {
- return INITIALIZING.order == this.order;
- }
-
- public boolean isConfigured() {
- return this.order >= CONFIGURING.order;
- }
- }
在AbstractConfiguredSecurityBuilder中与configurers相关的部分代码如下:
- public abstract class AbstractConfiguredSecurityBuilder
extends SecurityBuilder> extends AbstractSecurityBuilder { -
- private final LinkedHashMap
extends SecurityConfigurer>, List>> configurers; - private final List
> configurersAddedInInitializing; - private final Map
, Object> sharedObjects; - private final boolean allowConfigurersOfSameType;
- private BuildState buildState;
- private ObjectPostProcessor
-
- //向configures变量添加配置类,调用add方法
- public
extends SecurityConfigurerAdapter> C apply(C configurer) throws Exception { - configurer.addObjectPostProcessor(this.objectPostProcessor);
- configurer.setBuilder(this);
- this.add(configurer);
- return configurer;
- }
-
- public
extends SecurityConfigurer> C apply(C configurer) throws Exception { - this.add(configurer);
- return configurer;
- }
-
- //将所有的配置类保存到configures中,默认情况下,allowConfigurersOfSameType为false,所以List集合中的
- //配置类始终只有一个
- private
extends SecurityConfigurer> void add(C configurer) { - Assert.notNull(configurer, "configurer cannot be null");
- Class extends SecurityConfigurer
> clazz = configurer.getClass(); - synchronized(this.configurers) {
- if (this.buildState.isConfigured()) {
- throw new IllegalStateException("Cannot apply " + configurer + " to already built object");
- } else {
- List
> configs = null; - if (this.allowConfigurersOfSameType) {
- configs = (List)this.configurers.get(clazz);
- }
-
- List
> configs = configs != null ? configs : new ArrayList(1); - ((List)configs).add(configurer);
- this.configurers.put(clazz, configs);
- if (this.buildState.isInitializing()) {
- this.configurersAddedInInitializing.add(configurer);
- }
- }
- }
- }
- }
在AbstractConfiguredSecurityBuilder中与构建相关的部分代码如下:
- //一边更新状态,一边执行构建方法
- protected final O doBuild() throws Exception {
- synchronized(this.configurers) {
- this.buildState = AbstractConfiguredSecurityBuilder.BuildState.INITIALIZING;
- this.beforeInit();
- this.init();
- this.buildState = AbstractConfiguredSecurityBuilder.BuildState.CONFIGURING;
- this.beforeConfigure();
- this.configure();
- this.buildState = AbstractConfiguredSecurityBuilder.BuildState.BUILDING;
- O result = this.performBuild();
- this.buildState = AbstractConfiguredSecurityBuilder.BuildState.BUILT;
- return result;
- }
- }
-
- protected void beforeInit() throws Exception {
- }
-
- protected void beforeConfigure() throws Exception {
- }
-
- protected abstract O performBuild() throws Exception;
-
- //遍历所有配置类,并调用其init方法完成初始化操作
- private void init() throws Exception {
- Collection
> configurers = getConfigurers(); - for (SecurityConfigurer
configurer : configurers) { - configurer.init((B) this);
- }
- for (SecurityConfigurer
configurer : this.configurersAddedInInitializing) { - configurer.init((B) this);
- }
- }
-
- private void configure() throws Exception {
- Collection
> configurers = getConfigurers(); - for (SecurityConfigurer
configurer : configurers) { - configurer.configure((B) this);
- }
- }
ProviderManagerBuilder通过范型指定构建对象为AuthenticationManager
- public interface ProviderManagerBuilderextends ProviderManagerBuilder>
- extends SecurityBuilder
{ -
- B authenticationProvider(AuthenticationProvider authenticationProvider);
- }
AuthenticationManagerBuilder用来构建AuthenticationManager对象,他继承自AbstractConfiguredSecurityBuilder
- public class AuthenticationManagerBuilder extends AbstractConfiguredSecurityBuilder
implements ProviderManagerBuilder { -
- private AuthenticationManager parentAuthenticationManager;
- private List
authenticationProviders = new ArrayList(); - private UserDetailsService defaultUserDetailsService;
- private Boolean eraseCredentials;
- private AuthenticationEventPublisher eventPublisher;
-
- //表示允许相同类型的配置类同时存在
- public AuthenticationManagerBuilder(ObjectPostProcessor {
- super(objectPostProcessor, true);
- }
-
- public AuthenticationManagerBuilder parentAuthenticationManager(AuthenticationManager authenticationManager) {
- if (authenticationManager instanceof ProviderManager) {
- this.eraseCredentials(((ProviderManager)authenticationManager).isEraseCredentialsAfterAuthentication());
- }
-
- this.parentAuthenticationManager = authenticationManager;
- return this;
- }
-
- public AuthenticationManagerBuilder eraseCredentials(boolean eraseCredentials) {
- this.eraseCredentials = eraseCredentials;
- return this;
- }
-
- //配置基于内存的数据源,会创建一个InMemoryUserDetailsManagerConfigurer配置类,并最终
- //将该配置类添加到父类的configurers变量中,由于设置了允许相同类型的配置类同时存在
- //因此该方法可以被调用多次
- public InMemoryUserDetailsManagerConfigurer
inMemoryAuthentication() throws Exception { - return (InMemoryUserDetailsManagerConfigurer)this.apply(new InMemoryUserDetailsManagerConfigurer());
- }
-
- public JdbcUserDetailsManagerConfigurer
jdbcAuthentication() throws Exception { - return (JdbcUserDetailsManagerConfigurer)this.apply(new JdbcUserDetailsManagerConfigurer());
- }
-
- public
extends UserDetailsService> DaoAuthenticationConfigurer userDetailsService(T userDetailsService) throws Exception { - this.defaultUserDetailsService = userDetailsService;
- return (DaoAuthenticationConfigurer)this.apply(new DaoAuthenticationConfigurer(userDetailsService));
- }
-
- public AuthenticationManagerBuilder authenticationProvider(AuthenticationProvider authenticationProvider) {
- this.authenticationProviders.add(authenticationProvider);
- return this;
- }
-
- //创建和配置AuthenticationManager的实现类ProviderManager
- //ProviderManager创建成功后,会调用后置处理器处理一遍后再返回
- protected ProviderManager performBuild() throws Exception {
- if (!this.isConfigured()) {
- this.logger.debug("No authenticationProviders and no parentAuthenticationManager defined. Returning null.");
- return null;
- } else {
- ProviderManager providerManager = new ProviderManager(this.authenticationProviders, this.parentAuthenticationManager);
- if (this.eraseCredentials != null) {
- providerManager.setEraseCredentialsAfterAuthentication(this.eraseCredentials);
- }
-
- if (this.eventPublisher != null) {
- providerManager.setAuthenticationEventPublisher(this.eventPublisher);
- }
-
- providerManager = (ProviderManager)this.postProcess(providerManager);
- return providerManager;
- }
- }
-
- private
extends UserDetailsAwareConfigurerextends UserDetailsService>> C apply(C configurer) throws Exception { - this.defaultUserDetailsService = configurer.getUserDetailsService();
- return (UserDetailsAwareConfigurer)super.apply(configurer);
- }
- }
HttpSecurity的主要作用是用来构建一条过滤器链,也就是构建一个DefaultSecurityFilterChain对象。一个DefaultSecurityFilterChain对象包含一个路径匹配器和多个Spring Security过滤器,HttpSecurity中通过收集各种各样的xxxConfigurer,将Spring Security过滤器对应的配置类收集起来,并保存到父类AbstractConfiguredSecurityBuilder的configurers变量中。
在后续的构建过程中,再将这些xxxConfigurer构建为具体的Spring Security过滤器,并添加到filters对象中。