前篇:Spring Security源码学习——建造者基础架构
WebSecurity 的目标是构建 FilterChainProxy 对象,即构建核心过滤器 springSecurityFilterChain
主要关注由 AbstractConfiguredSecurityBuilder 继承下来的方法实现 performBuild()
public final class WebSecurity extends AbstractConfiguredSecurityBuilder<Filter, WebSecurity> implements SecurityBuilder<Filter>, ApplicationContextAware { private final List<RequestMatcher> ignoredRequests = new ArrayList<>(); private final List<SecurityBuilder<? extends SecurityFilterChain>> securityFilterChainBuilders = new ArrayList<>(); private IgnoredRequestConfigurer ignoredRequestRegistry; private FilterSecurityInterceptor filterSecurityInterceptor; private HttpFirewall httpFirewall; private boolean debugEnabled; private WebInvocationPrivilegeEvaluator privilegeEvaluator; private DefaultWebSecurityExpressionHandler defaultWebSecurityExpressionHandler = new DefaultWebSecurityExpressionHandler(); private SecurityExpressionHandler<FilterInvocation> expressionHandler = defaultWebSecurityExpressionHandler; @Override protected Filter performBuild() throws Exception { int chainSize = ignoredRequests.size() + securityFilterChainBuilders.size(); //创建了一个 SecurityFilterChain存储器 List<SecurityFilterChain> securityFilterChains = new ArrayList<>( chainSize); //将那些忽略拦截的URL封装成一堆 DefaultSecurityFilterChain 添加进 securityFilterChains for (RequestMatcher ignoredRequest : ignoredRequests) { securityFilterChains.add(new DefaultSecurityFilterChain(ignoredRequest)); } //调用的是 build() 方法,其实它最终调用的是 HttpSecurity 实现的 performBuild() 方法,返回值也是 DefaultSecurityFilterChain,随后添加进 securityFilterChains for (SecurityBuilder<? extends SecurityFilterChain> securityFilterChainBuilder : securityFilterChainBuilders) { securityFilterChains.add(securityFilterChainBuilder.build()); } //根据securityFilterChains 创建出 FilterChainProxy 对象。 FilterChainProxy filterChainProxy = new FilterChainProxy(securityFilterChains); if (httpFirewall != null) { filterChainProxy.setFirewall(httpFirewall); } filterChainProxy.afterPropertiesSet(); Filter result = filterChainProxy; if (debugEnabled) { logger.warn(""); result = new DebugFilter(filterChainProxy); } postBuildAction.run(); return result; } }
@Configuration(proxyBeanMethods = false) public class WebSecurityConfiguration implements ImportAware, BeanClassLoaderAware { private WebSecurity webSecurity; private Boolean debugEnabled; private List<SecurityConfigurer<Filter, WebSecurity>> webSecurityConfigurers; private ClassLoader beanClassLoader; @Autowired(required = false) private ObjectPostProcessor<Object> objectObjectPostProcessor; @Autowired(required = false) public void setFilterChainProxySecurityConfigurer( ObjectPostProcessor<Object> objectPostProcessor, @Value("#{@autowiredWebSecurityConfigurersIgnoreParents.getWebSecurityConfigurers()}") List<SecurityConfigurer<Filter, WebSecurity>> webSecurityConfigurers) throws Exception { //创建WebSecurity webSecurity = objectPostProcessor.postProcess(new WebSecurity(objectPostProcessor)); if (debugEnabled != null) { webSecurity.debug(debugEnabled); } webSecurityConfigurers.sort(AnnotationAwareOrderComparator.INSTANCE); Integer previousOrder = null; Object previousConfig = null; for (SecurityConfigurer<Filter, WebSecurity> config : webSecurityConfigurers) { Integer order = AnnotationAwareOrderComparator.lookupOrder(config); if (previousOrder != null && previousOrder.equals(order)) { throw new IllegalStateException(""); } previousOrder = order; previousConfig = config; } for (SecurityConfigurer<Filter, WebSecurity> webSecurityConfigurer : webSecurityConfigurers) { webSecurity.apply(webSecurityConfigurer); } this.webSecurityConfigurers = webSecurityConfigurers; }
1、实例化并获取容器中的ObjectPostProcessor
2、实例化容器中名字是autowiredWebSecurityConfigurersIgnoreParents
的bean并调用其getWebSecurityConfigurers方法,实例化并获取容器中的所有的WebSecurityConfigurer
。默认情况下,容器中只有一个WebSecurityConfigurer,那就是DefaultConfigurerAdapter
从 SpringSecurity源码学习之SpringSecurity相关配置类的读取中,我们知道DefaultConfigurerAdapter是在SpringBootWebSecurityConfiguration中注册
@Configuration(proxyBeanMethods = false) @ConditionalOnClass(WebSecurityConfigurerAdapter.class) @ConditionalOnMissingBean(WebSecurityConfigurerAdapter.class) @ConditionalOnWebApplication(type = Type.SERVLET) public class SpringBootWebSecurityConfiguration { @Configuration(proxyBeanMethods = false) @Order(SecurityProperties.BASIC_AUTH_ORDER) static class DefaultConfigurerAdapter extends WebSecurityConfigurerAdapter { } }
从上面代码中的@ConditionalOnMissingBean,我们可以知道,如果我们注册了自己的WebSecurityConfigurerAdapter,那么DefaultConfigurerAdapter就不会注册