Spring Security源码学习——建造者之WebSecurity

2021/9/18 17:07:17

本文主要是介绍Spring Security源码学习——建造者之WebSecurity,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

前篇: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;
	}

}

二、WebSecurity的初始化

@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就不会注册



这篇关于Spring Security源码学习——建造者之WebSecurity的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程