Spring Security启动流程

在这里插入图片描述

SecurityConfigurer

用来配置SecurityBuilder的超类。
所有SecurityConfigurer首先调用其init(SecurityBuilder)方法。
再调用了所有init(SecurityBuilder)方法之后,调用每个configure(SecurityBuilder)方法。

public interface SecurityConfigurer<O, B extends SecurityBuilder<O>> {
	/**
	初始化SecurityBuilder。
	在这里,只应创建和修改共享状态,而不应创建和修改用于构建对象的SecurityBuilder上的属性。
	这可确保Configure(SecurityBuilder)方法在生成时使用正确的共享对象。
	 */
	void init(B builder) throws Exception;
	/**
	 通过设置SecurityBuilder上的必要属性来配置SecurityBuilder
	 */
	void configure(B builder) throws Exception;
}
WebSecurityConfigurer

对 WebSecurity进行配置。
在大多数情况下,用户将使用EnableWebSecurity和扩展WebSecurityConfigurerAdapter来进行 WebSecurity的配置,该配置将通过EnableWebSecurity注释自动应用于WebSecurity。

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

为创建WebSecurityConfigurer实例提供方便的基类。该实现允许通过重写方法进行自定义。

@Order(100)
public abstract class WebSecurityConfigurerAdapter implements
		WebSecurityConfigurer<WebSecurity> {

	public void init(final WebSecurity web) throws Exception {
		final HttpSecurity http = getHttp();
		web.addSecurityFilterChainBuilder(http).postBuildAction(new Runnable() {
			public void run() {
				FilterSecurityInterceptor securityInterceptor = http
						.getSharedObject(FilterSecurityInterceptor.class);
				web.securityInterceptor(securityInterceptor);
			}
		});
	}
	
	/**
	 * 重写此方法以配置 WebSecurity。例如,如果您希望忽略某些请求。
	 */
	public void configure(WebSecurity web) throws Exception { }
	
	/*
	重写此方法以配置HttpSecurity。通常,子类不应该通过调用Super来调用此方法,因为它可能会覆盖它们的配置。
	*/
	protected void configure(HttpSecurity http) throws Exception {
		http.authorizeRequests()
				.anyRequest().authenticated()
				.and()
			.formLogin().and()
			.httpBasic();
	}
}

在这里插入图片描述

SecurityBuilder

用于构建对象的超类

public interface SecurityBuilder<O> {
	/*
	 生成对象并返回或null
	 */
	O build() throws Exception;
}
AbstractSecurityBuilder

一个基本的SecurityBuilder,用于确保正在生成的对象只生成一次

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;
	}
	protected abstract O doBuild() throws Exception;
}
AbstractConfiguredSecurityBuilder

对SecurityBuilder的基本扩展。
可以将多个SecurityConfigurer应用到SecurityBuilder,
这使得修改SecurityBuilder成为一种策略,可以对其进行定制并将其分解为多个SecurityConfigurer对象,这些对象具有比SecurityBuilder更具体的目标。
例如,SecurityBuilder可以构建DelegatingFilterProxy,但SecurityConfigurer可以使用会话管理、基于表单的登录、授权等所需的Filter填充SecurityBuilder。

public abstract class AbstractConfiguredSecurityBuilder<O, B extends SecurityBuilder<O>>
		extends AbstractSecurityBuilder<O> {
	/*
	将SecurityConfigureAdapter应用于此SecurityBuilder并调用SecurityConfigureAdapter.setBuilder(SecurityBuilder)
	*/
	public <C extends SecurityConfigurerAdapter<O, B>> C apply(C configurer)
			throws Exception {
		configurer.addObjectPostProcessor(objectPostProcessor);
		configurer.setBuilder((B) this);
		add(configurer);
		return configurer;
	}
	/*
	将SecurityConfigure应用于此SecurityBuilder,覆盖完全相同类的任何SecurityConfigure
	*/
	public <C extends SecurityConfigurer<O, B>> C apply(C configurer) throws Exception {
		add(configurer);
		return configurer;
	}
	/*
	设置由多个SecurityConfigure共享的对象
	*/
	public <C> void setSharedObject(Class<C> sharedType, C object) {
		this.sharedObjects.put(sharedType, object);
	}
	/*
	获取一个共享对象。请注意,不考虑对象继承人
	*/
	public <C> C getSharedObject(Class<C> sharedType) {
		return (C) this.sharedObjects.get(sharedType);
	}
	/*
	将构建过程拆解为多个步骤,并提供给给子类重写的机会(模板方法)
	*/
	@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;
		}
	}
}
WebSecurity

WebSecurity由WebSecurityConfiguration配置创建,以创建FilterChainProxy,称为Spring安全过滤器链(springSecurityFilterChain)。springSecurityFilterChain是DelegatingFilterProxy委托给的筛选器。 可以通过创建WebSecurityConfigurer或更可能通过重写WebSecurityConfigureAdapter来定制WebSecurity。

public final class WebSecurity extends
		AbstractConfiguredSecurityBuilder<Filter, WebSecurity> implements
		SecurityBuilder<Filter>, ApplicationContextAware {
	@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();
		List<SecurityFilterChain> securityFilterChains = new ArrayList<>(
				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;
		if (debugEnabled) {
			logger.warn("\n\n"
					+ "********************************************************************\n"
					+ "**********        Security debugging is enabled.       *************\n"
					+ "**********    This may include sensitive information.  *************\n"
					+ "**********      Do not use in a production system!     *************\n"
					+ "********************************************************************\n\n");
			result = new DebugFilter(filterChainProxy);
		}
		postBuildAction.run();
		return result;
	}
}
HttpSecurity

HttpSecurity类似于名称空间配置中的Spring Security的XML元素。
它允许为特定的http请求配置基于Web的安全性。
默认情况下,它将应用于所有请求,但可以使用questMatcher(RequestMatcher)或其他类似方法进行限制。
这里HttpSecurity就是构建FilterChainProxy(springSecurityFilterChain)中的filterChains;

public final class HttpSecurity extends
		AbstractConfiguredSecurityBuilder<**DefaultSecurityFilterChain**, **HttpSecurity**>
		implements SecurityBuilder<**DefaultSecurityFilterChain**>,
		HttpSecurityBuilder<HttpSecurity> {
	private final RequestMatcherConfigurer requestMatcherConfigurer;
	private List<Filter> filters = new ArrayList<>();
	private RequestMatcher requestMatcher = AnyRequestMatcher.INSTANCE;
	private FilterComparator comparator = new FilterComparator();
	/*
	这里先会对Filter进行排序,排序规则在FilterComparator中定义
	*/
	@Override
	protected DefaultSecurityFilterChain performBuild() throws Exception {
		Collections.sort(filters, comparator);
		return new DefaultSecurityFilterChain(requestMatcher, filters);
	}
}
xxx

xxx
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值