Spring Security源码解析(二)——引入

目录

Spring Security的引入

AuthenticationConfiguration

WebSecurityConfiguration

引入 FilterChain。

设置FilterChain的配置信息。

 

 WebSecurity

AbstractConfiguredSecurityBuilder

属性

doBuild()方法

WebSecurity

属性

 performBuild()

WebSecurityConfigurerAdapter

类图

属性

init()方法

configure()方法

getHttp()方法

HttpSecurity

类图

 HttpSecurityBuilder

HttpSecurity

属性

构造函数

performBuild

AuthenticationManagerBuilder配置。


https://github.com/spring-cloud/spring-cloud-security/tree/v2.2.1.RELEASE

Spring Security的引入

在使用Spring Security时,会定义一个WebSecurityConfigurerAdapter的子类,并同时加上注解@EnableWebSecurity

// org.springframework.security.config.annotation.web.configuration;
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter 

@EnableWebSecurity用于引入security功能,WebSecurityConfigurerAdapter实现类用于扩展功能。

@Import({ WebSecurityConfiguration.class,
		SpringWebMvcImportSelector.class,
		OAuth2ImportSelector.class })
@EnableGlobalAuthentication
@Configuration
public @interface EnableWebSecurity {

	/**
	 * Controls debugging support for Spring Security. Default is false.
	 * @return if true, enables debug support with Spring Security
	 */
	boolean debug() default false;
}

@EnableWebSecurity又会引入@EnableGlobalAuthentication

@Import(AuthenticationConfiguration.class)
@Configuration
public @interface EnableGlobalAuthentication {
}

因此会导入几个类:

  • AuthenticationConfiguration。
  • WebSecurityConfiguration。引入FilterChain
  • SpringWebMvcImportSelector。判断是否引入了Spring MVC。
  • OAuth2ImportSelector。判断是否引入了OAuth2。

AuthenticationConfiguration

@Import(ObjectPostProcessorConfiguration.class)
public class AuthenticationConfiguration {
 

	@Bean
	public AuthenticationManagerBuilder authenticationManagerBuilder(
			ObjectPostProcessor<Object> objectPostProcessor, ApplicationContext context) {
		LazyPasswordEncoder defaultPasswordEncoder = new LazyPasswordEncoder(context);
		AuthenticationEventPublisher authenticationEventPublisher = getBeanOrNull(context, AuthenticationEventPublisher.class);

		DefaultPasswordEncoderAuthenticationManagerBuilder result = new DefaultPasswordEncoderAuthenticationManagerBuilder(objectPostProcessor, defaultPasswordEncoder);
		if (authenticationEventPublisher != null) {
			result.authenticationEventPublisher(authenticationEventPublisher);
		}
		return result;
	}

	@Bean
	public static GlobalAuthenticationConfigurerAdapter enableGlobalAuthenticationAutowiredConfigurer(
			ApplicationContext context) {
		return new EnableGlobalAuthenticationAutowiredConfigurer(context);
	}

	@Bean
	public static InitializeUserDetailsBeanManagerConfigurer initializeUserDetailsBeanManagerConfigurer(ApplicationContext context) {
		return new InitializeUserDetailsBeanManagerConfigurer(context);
	}

	@Bean
	public static InitializeAuthenticationProviderBeanManagerConfigurer initializeAuthenticationProviderBeanManagerConfigurer(ApplicationContext context) {
		return new InitializeAuthenticationProviderBeanManagerConfigurer(context);
	}


}

WebSecurityConfiguration

引入 FilterChain

创建名称为springSecurityFilterChain的Filter 

//public static final String DEFAULT_FILTER_NAME = "springSecurityFilterChain";
@Bean(name = AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME)
	public Filter springSecurityFilterChain() throws Exception {
//判断是否自定义了SecurityConfigurer
		boolean hasConfigurers = webSecurityConfigurers != null
				&& !webSecurityConfigurers.isEmpty();
		if (!hasConfigurers) {
//如果没有自定义,则使用默认的。
			WebSecurityConfigurerAdapter adapter = objectObjectPostProcessor
					.postProcess(new WebSecurityConfigurerAdapter() {
					});
			webSecurity.apply(adapter);
		}
//builder 返回一个Filter
		return webSecurity.build();
	}

设置FilterChain的配置信息。

创建了一个WebSecurity。

@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排序。通过@Order注解。
		webSecurityConfigurers.sort(AnnotationAwareOrderComparator.INSTANCE);

//对Order进行比较是否有相同的(保证不相同),由于前面进行了排序,只要比较前后有相同的就可以
		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(
						"@Order on WebSecurityConfigurers must be unique. Order of "
								+ order + " was already used on " + previousConfig + ", so it cannot be used on "
								+ config + " too.");
			}
			previousOrder = order;
			previousConfig = config;
		}
		for (SecurityConfigurer<Filter, WebSecurity> webSecurityConfigurer : webSecurityConfigurers) {
//webSecurity 应用配置。
			webSecurity.apply(webSecurityConfigurer);
		}
		this.webSecurityConfigurers = webSecurityConfigurers;
	}

获取configurers。一般返回的就是自定义的WebSecurityConfigurer

@Value("#{@autowiredWebSecurityConfigurersIgnoreParents.getWebSecurityConfigurers()}") List<SecurityConfigurer<Filter, WebSecurity>> webSecurityConfigurers
	public List<SecurityConfigurer<Filter, WebSecurity>> getWebSecurityConfigurers() {
		List<SecurityConfigurer<Filter, WebSecurity>> webSecurityConfigurers = new ArrayList<>();
//获取所有WebSecurityConfigurer的实现类。
		Map<String, WebSecurityConfigurer> beansOfType = beanFactory
				.getBeansOfType(WebSecurityConfigurer.class);
		for (Entry<String, WebSecurityConfigurer> entry : beansOfType.entrySet()) {
			webSecurityConfigurers.add(entry.getValue());
		}
		return webSecurityConfigurers;
	}

 

 WebSecurity

Filter的创建,最终是通过WebSecurity的实例的build()方法实现。

WebSecurity的类继承如下图:

  • SecurityBuilder定义了构建的接口标准
  • AbstractSecurityBuilder实现build方法,用AtomicBoolean的变量building保证多线程情况下,操作的原子性。此处采用的是模板模式。定义了doBuild()抽象方法
  • AbstractConfiguredSecurityBuilder 继承AbstractSecurityBuilder实现doBuild()方法,也采用模板模式,定义了实现的具体的步骤。
public interface SecurityBuilder<O> {
	O build() throws Exception;
}
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;
}

AbstractConfiguredSecurityBuilder

属性

public abstract class AbstractConfiguredSecurityBuilder<O, B extends SecurityBuilder<O>>
		extends AbstractSecurityBuilder<O> {

//SecurityConfigurer 列表。
	private final LinkedHashMap<Class<? extends SecurityConfigurer<O, B>>, List<SecurityConfigurer<O, B>>> configurers = new LinkedHashMap<>();
	private final List<SecurityConfigurer<O, B>> configurersAddedInInitializing = new ArrayList<>();

	private final Map<Class<?>, Object> sharedObjects = new HashMap<>();

	private final boolean allowConfigurersOfSameType;
//当前状态。
	private BuildState buildState = BuildState.UNBUILT;

	private ObjectPostProcessor<Object> objectPostProcessor;
}

doBuild()方法

doBuild()方法的步骤:

  1. beforeInit。空实现,可由子类覆盖。
  2. init。
  3. beforeConfigure。空实现,可由子类覆盖。
  4. configure
  5. performBuild。由子类实现。
@Override
	protected final O doBuild() throws Exception {
		synchronized (configurers) {
			buildState = BuildState.INITIALIZING;

			beforeInit();
			init();

			buildState = BuildState.CONFIGURING;

			beforeConfigure();
			configure();

			buildState = BuildState.BUILDING;

			O result = performBuild();

			buildState = BuildState.BUILT;

			return result;
		}
	}
	private Collection<SecurityConfigurer<O, B>> getConfigurers() {
		List<SecurityConfigurer<O, B>> result = new ArrayList<>();
		for (List<SecurityConfigurer<O, B>> configs : this.configurers.values()) {
			result.addAll(configs);
		}
		return result;
	}

init()方法

	private void init() throws Exception {
		Collection<SecurityConfigurer<O, B>> configurers = getConfigurers();

//循环所有的configurer ,调用其初始化。
		for (SecurityConfigurer<O, B> configurer : configurers) {
			configurer.init((B) this);
		}

		for (SecurityConfigurer<O, B> configurer : configurersAddedInInitializing) {
			configurer.init((B) this);
		}
	}

configure()方法

	private void configure() throws Exception {
		Collection<SecurityConfigurer<O, B>> configurers = getConfigurers();
//循环调用configurer 的configure()方法。
		for (SecurityConfigurer<O, B> configurer : configurers) {
			configurer.configure((B) this);
		}
	}

apply()方法

apply方法用于设置SecurityConfigurer的属性,并加入到此builder的configurers中。

    public <C extends SecurityConfigurerAdapter<O, B>> C apply(C configurer) throws Exception {
		configurer.addObjectPostProcessor(objectPostProcessor);
		configurer.setBuilder((B) this);
		add(configurer);
		return configurer;
	}


	public <C extends SecurityConfigurer<O, B>> C apply(C configurer) throws Exception {
		add(configurer);
		return configurer;
	}

WebSecurity

属性

//忽略权限控制的请求 Matcher。
private final List<RequestMatcher> ignoredRequests = new ArrayList<>();
//构造SecurityFilterChain 的Buidler列表。
	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;

	private Runnable postBuildAction = () -> {
	};

 performBuild()

真实构造FilterChain:FilterChainProxy 


@Override
	protected Filter performBuild() throws Exception {
		Assert.state(
				!securityFilterChainBuilders.isEmpty(),
				() -> "At least one SecurityBuilder<? extends SecurityFilterChain> needs to be specified. "
						+ "Typically this done by adding a @Configuration that extends WebSecurityConfigurerAdapter. "
						+ "More advanced users can invoke "
						+ WebSecurity.class.getSimpleName()
						+ ".addSecurityFilterChainBuilder directly");
		int chainSize = ignoredRequests.size() + securityFilterChainBuilders.size();
        //securityFilterChains
		List<SecurityFilterChain> securityFilterChains = new ArrayList<>(
				chainSize);
        //如果是ignoredRequest类型的,那么久添加默认过滤器链(DefaultSecurityFilterChain)       
		for (RequestMatcher ignoredRequest : ignoredRequests) {
			securityFilterChains.add(new DefaultSecurityFilterChain(ignoredRequest));
		}
        //如果是securityFilterChainBuilder类型的,那么通过securityFilterChainBuilder的build()方法来构建过滤器链
		for (SecurityBuilder<? extends SecurityFilterChain> securityFilterChainBuilder : securityFilterChainBuilders) {
			securityFilterChains.add(securityFilterChainBuilder.build());
		}
        //将过滤器链交给一个过滤器链代理对象,此代理对象里面存储的是所有FilterChain。
		FilterChainProxy filterChainProxy = new FilterChainProxy(securityFilterChains);
		if (httpFirewall != null) {
			filterChainProxy.setFirewall(httpFirewall);
		}
		filterChainProxy.afterPropertiesSet();

		Filter result = filterChainProxy;
		if (debugEnabled) {

			result = new DebugFilter(filterChainProxy);
		}
        //构造完后处理。
		postBuildAction.run();
		return result;
	}

WebSecurityConfigurerAdapter

类图

public interface SecurityConfigurer<O, B extends SecurityBuilder<O>> {

	void init(B builder) throws Exception;

	void configure(B builder) throws Exception;
}

 WebSecurityConfigurer构造的是Filter的实例。

public interface WebSecurityConfigurer<T extends SecurityBuilder<Filter>> extends
		SecurityConfigurer<Filter, T> {

}

属性

使用WebSecurity作为Filter的builder

@Order(100)
public abstract class WebSecurityConfigurerAdapter implements

		WebSecurityConfigurer<WebSecurity> {
	
	private ApplicationContext context;

	private ContentNegotiationStrategy contentNegotiationStrategy = new HeaderContentNegotiationStrategy();

	private ObjectPostProcessor<Object> objectPostProcessor = new ObjectPostProcessor<Object>() {
		public <T> T postProcess(T object) {
			throw new IllegalStateException(
					ObjectPostProcessor.class.getName()
							+ " is a required bean. Ensure you have used @EnableWebSecurity and @Configuration");
		}
	};

	private AuthenticationConfiguration authenticationConfiguration;

	private AuthenticationManagerBuilder authenticationBuilder;
	private AuthenticationManagerBuilder localConfigureAuthenticationBldr;
	private boolean disableLocalConfigureAuthenticationBldr;
	private boolean authenticationManagerInitialized;
	private AuthenticationManager authenticationManager;
	private AuthenticationTrustResolver trustResolver = new AuthenticationTrustResolverImpl();
	private HttpSecurity http;
//是否可使用默认值。
	private boolean disableDefaults;

init()方法

通过getHttp()方法构造HttpSecurity,并设置为WebSecurity的builder。

	public void init(final WebSecurity web) throws Exception {
//构造 HttpSecurity 
		final HttpSecurity http = getHttp();
//添加chain  builder,类型为SecurityBuilder<? extends SecurityFilterChain>。
		web.addSecurityFilterChainBuilder(http)
.postBuildAction(() -> {
			FilterSecurityInterceptor securityInterceptor = http
					.getSharedObject(FilterSecurityInterceptor.class);
			web.securityInterceptor(securityInterceptor);
		});
	}

configure()方法

空实现。子类可覆盖。

	public void configure(WebSecurity web) throws Exception {
	}

getHttp()方法

protected final HttpSecurity getHttp() throws Exception {
		if (http != null) {
			return http;
		}
//S1:
		DefaultAuthenticationEventPublisher eventPublisher = objectPostProcessor
				.postProcess(new DefaultAuthenticationEventPublisher());
		localConfigureAuthenticationBldr.authenticationEventPublisher(eventPublisher);
//S2:
		AuthenticationManager authenticationManager = authenticationManager();
		authenticationBuilder.parentAuthenticationManager(authenticationManager);
		authenticationBuilder.authenticationEventPublisher(eventPublisher);
		Map<Class<?>, Object> sharedObjects = createSharedObjects();
//S3:
		http = new HttpSecurity(objectPostProcessor, authenticationBuilder,
				sharedObjects);
		if (!disableDefaults) {
//S4:
			// @formatter:off
			http
				.csrf().and()
				.addFilter(new WebAsyncManagerIntegrationFilter())
				.exceptionHandling().and()
				.headers().and()
				.sessionManagement().and()
				.securityContext().and()
				.requestCache().and()
				.anonymous().and()
				.servletApi().and()
				.apply(new DefaultLoginPageConfigurer<>()).and()
				.logout();
			// @formatter:on
			ClassLoader classLoader = this.context.getClassLoader();
//加载所有的AbstractHttpConfigurer子类。并应用apply方法。
			List<AbstractHttpConfigurer> defaultHttpConfigurers =
					SpringFactoriesLoader.loadFactories(AbstractHttpConfigurer.class, classLoader);

			for (AbstractHttpConfigurer configurer : defaultHttpConfigurers) {
				http.apply(configurer);
			}
		}
//S5:
		configure(http);
		return http;
	}

步骤:

S1:
S2:构造AuthenticationManager 。
S3:构造HttpSecurity。

S4:如果不禁用默认值,则使用默认configurer设置HttpSecurity。

S5:配置HttpSecurity

	protected void configure(HttpSecurity http) throws Exception {

		http
			.authorizeRequests()
				.anyRequest().authenticated()
				.and()
			.formLogin().and()
			.httpBasic();
	}

HttpSecurity

HttpSecurity是一个Builder,用于构造FilterChain。

类图

 HttpSecurityBuilder

用于构造DefaultSecurityFilterChain。可维护Builder的属性。提供了设置 用于认证的bean的方法。

public interface HttpSecurityBuilder<H extends HttpSecurityBuilder<H>> extends
		SecurityBuilder<DefaultSecurityFilterChain> {


	<C extends SecurityConfigurer<DefaultSecurityFilterChain, H>> C getConfigurer(
			Class<C> clazz);

	<C extends SecurityConfigurer<DefaultSecurityFilterChain, H>> C removeConfigurer(
			Class<C> clazz);

	<C> void setSharedObject(Class<C> sharedType, C object);

	<C> C getSharedObject(Class<C> sharedType);

	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);

	H addFilter(Filter filter);
}

HttpSecurity

属性

//请求匹配过滤的配置信息	
private final RequestMatcherConfigurer requestMatcherConfigurer;
//过滤器列表
	private List<Filter> filters = new ArrayList<>();
//匹配任何请求的匹配器
	private RequestMatcher requestMatcher = AnyRequestMatcher.INSTANCE;
//过滤器比较。
	private FilterComparator comparator = new FilterComparator();

 FilterComparator 

用于Filter排序。并定义了常用Filter的Order顺序。初始值100,步长100。可以通过 方法在某个Filter前面后者后面加Filter。

final class FilterComparator implements Comparator<Filter>, Serializable {
	public int compare(Filter lhs, Filter rhs) {
		Integer left = getOrder(lhs.getClass());
		Integer right = getOrder(rhs.getClass());
		return left - right;
	}
}
	private static final int INITIAL_ORDER = 100;
	private static final int ORDER_STEP = 100;
FilterComparator() {
		Step order = new Step(INITIAL_ORDER, ORDER_STEP);
		put(ChannelProcessingFilter.class, order.next());
		put(ConcurrentSessionFilter.class, order.next());
		put(WebAsyncManagerIntegrationFilter.class, order.next());
		put(SecurityContextPersistenceFilter.class, order.next());
		put(HeaderWriterFilter.class, order.next());
... ...
	private final Map<String, Integer> filterToOrder = new HashMap<>();

    public void registerAfter(Class<? extends Filter> filter,
			Class<? extends Filter> afterFilter) {
		Integer position = getOrder(afterFilter);
		if (position == null) {
			throw new IllegalArgumentException(
					"Cannot register after unregistered Filter " + afterFilter);
		}

		put(filter, position + 1);
	}

 RequestMatcher 

用于判断request是否匹配,并返回匹配结果。

public interface RequestMatcher {

	boolean matches(HttpServletRequest request);
	default MatchResult matcher(HttpServletRequest request) {
		boolean match = matches(request);
		return new MatchResult(match, Collections.emptyMap());
	}


	class MatchResult {
		private final boolean match;
		private final Map<String, String> variables;

		MatchResult(boolean match, Map<String, String> variables) {
			this.match = match;
			this.variables = variables;
		}
}

}

 默认实现了很多个RequestMatcher。

 

public final class AnyRequestMatcher implements RequestMatcher {
	public static final RequestMatcher INSTANCE = new AnyRequestMatcher();

	public boolean matches(HttpServletRequest request) {
		return true;
	}
}


public final class AndRequestMatcher implements RequestMatcher {
	private final List<RequestMatcher> requestMatchers;
	public AndRequestMatcher(List<RequestMatcher> requestMatchers) {
... ... 
		this.requestMatchers = requestMatchers;
	}

	public AndRequestMatcher(RequestMatcher... requestMatchers) {
		this(Arrays.asList(requestMatchers));
	}

	public boolean matches(HttpServletRequest request) {
		for (RequestMatcher matcher : requestMatchers) {
			if (logger.isDebugEnabled()) {
				logger.debug("Trying to match using " + matcher);
			}
			if (!matcher.matches(request)) {
				logger.debug("Did not match");
				return false;
			}
		}
		return true;
	}
}    

构造函数

构造函数,保存了AuthenticationManagerBuilder实例,并保存了一些共用对象。

public HttpSecurity(ObjectPostProcessor<Object> objectPostProcessor,
			AuthenticationManagerBuilder authenticationBuilder,
			Map<Class<?>, Object> sharedObjects) {
		super(objectPostProcessor);
		Assert.notNull(authenticationBuilder, "authenticationBuilder cannot be null");
		setSharedObject(AuthenticationManagerBuilder.class, authenticationBuilder);
		for (Map.Entry<Class<?>, Object> entry : sharedObjects
				.entrySet()) {
			setSharedObject((Class<Object>) entry.getKey(), entry.getValue());
		}
		ApplicationContext context = (ApplicationContext) sharedObjects
				.get(ApplicationContext.class);
		this.requestMatcherConfigurer = new RequestMatcherConfigurer(context);
	}

performBuild

	@Override
	protected DefaultSecurityFilterChain performBuild() {
//排序
		filters.sort(comparator);
//构造DefaultSecurityFilterChain。会在每个configurer的configure()方法中,把filter加入到Filters
		return new DefaultSecurityFilterChain(requestMatcher, filters);
	}

 Filters通过addFilter 添加。

	public HttpSecurity addFilter(Filter filter) {
		Class<? extends Filter> filterClass = filter.getClass();
		if (!comparator.isRegistered(filterClass)) {
			throw new IllegalArgumentException(
					"The Filter class "
							+ filterClass.getName()
							+ " does not have a registered order and cannot be added without a specified order. Consider using addFilterBefore or addFilterAfter instead.");
		}
		this.filters.add(filter);
		return this;
	}

AuthenticationManagerBuilder配置。

AuthenticationManagerBuilder 配置AuthenticationProvider UserDetailsService 

	public HttpSecurity authenticationProvider(
			AuthenticationProvider authenticationProvider) {
		getAuthenticationRegistry().authenticationProvider(authenticationProvider);
		return this;
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see
	 * org.springframework.security.config.annotation.web.HttpSecurityBuilder#userDetailsService
	 * (org.springframework.security.core.userdetails.UserDetailsService)
	 */
	public HttpSecurity userDetailsService(UserDetailsService userDetailsService)
			throws Exception {
		getAuthenticationRegistry().userDetailsService(userDetailsService);
		return this;
	}

	private AuthenticationManagerBuilder getAuthenticationRegistry() {
		return getSharedObject(AuthenticationManagerBuilder.class);
	}

FilterChainProxy生成时序图

猜你喜欢

转载自blog.csdn.net/demon7552003/article/details/107250259