SpringSecurity中关键的类

Filter链相关接口

SpringSecurity简单理解,就是将一堆Filter通过SecurityFilterChain有效的组织起来,并通过代理的方式放到Spring中执行

  1. SecurityFilterChain表示在对需要处理的URL匹配时获取在该URL中对于的Filter列表
public interface SecurityFilterChain {
	// 当前FilterChain是否为需要执行filterchain处理的请求
	boolean matches(HttpServletRequest request);
	// matches匹配上后,对应的Filter链
	List<Filter> getFilters();
}
  1. FilterChainProxy对应有多个SecurityFilterChain,该类只是一个代理类,代理N个请求的处理链,
    其中getFilters根据匹配规则找到第一个匹配的SecurityFilterChain并通过VirtualFilterChain执行执行SecurityFilterChain中的filter方法
    真正执行的入口在doFilterInternal方法中,执行
private void doFilterInternal(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
		List<Filter> filters = getFilters(fwRequest);
		VirtualFilterChain vfc = new VirtualFilterChain(fwRequest, chain, filters);
		vfc.doFilter(fwRequest, fwResponse);
	}

找到请求执行的SecurityFilterChain

private List<Filter> getFilters(HttpServletRequest request) {
		for (SecurityFilterChain chain : filterChains) {
			if (chain.matches(request)) {
				return chain.getFilters(); //返回的实际是SecurityFilterChain下的所有filter
			}
		}
		return null;
	}

对匹配上的FilterChain按顺序执行Filter

// 内部类VirtualFilterChain
public void doFilter(ServletRequest request, ServletResponse response)
				throws IOException, ServletException {
		if (currentPosition == size) {
			// 执行ServletFilter,走下一个filter执行
			originalChain.doFilter(request, response);
		} else {
			currentPosition++;
			Filter nextFilter = additionalFilters.get(currentPosition - 1);
			nextFilter.doFilter(request, response, this);
		}
	}
}

可以看到FilterChainProxy是执行请求处理的核心,该类是如何创建的后面单点

  1. DelegatingFilterProxy作为Spring Security处理的入口
    类中的一个属性targetBeanName表示在IOC容器中的 FilterChainProxy bean的名字,默认有两个
  • SessionRepositoryFilter名字

  • SpringSecurityFilterChain
    可以看到启动时拿到的就是在这里插入图片描述
    那么这些Filter是如何,有效的组织起来的呢?
    实际上,就是使用构建者模式,通过WebSecurity,HttpSecurity这两个Builder构造出来的

SecurityFilterChain的构造

HttpSecurity构造出DefaultSecurityFilterChain,该DefaultSecurityFilterChain是一个默认实现
观测HttpSecurity可以发现SecurityBuilder接口定义出构建的成果是啥,AbstractConfiguredSecurityBuilder–>AbstractSecurityBuilder–>SecurityBuilder

public final class HttpSecurity extends
		AbstractConfiguredSecurityBuilder<DefaultSecurityFilterChain, HttpSecurity>
		implements SecurityBuilder<DefaultSecurityFilterChain>,
		HttpSecurityBuilder<HttpSecurity> {
}
//该类需要在Configurer的帮助下构建
public abstract class AbstractConfiguredSecurityBuilder<O, B extends SecurityBuilder<O>>
		extends AbstractSecurityBuilder<O> {
    @Override
	protected final O doBuild() throws Exception {
		synchronized (configurers) {
			buildState = BuildState.INITIALIZING;
			beforeInit();
			init();
			buildState = BuildState.CONFIGURING;
			beforeConfigure();
			configure(); //将所有的configurer应用到当前builder上,
			buildState = BuildState.BUILDING;
			O result = performBuild();
			buildState = BuildState.BUILT;
			return result;
		}
	}
}
//保证builder只初识化一次
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;
}
//SecurityBuilder
public interface SecurityBuilder<O> {
	O build() throws Exception;
}

简单理解就是SecurityBuilder在配置器SecurityConfigurer的帮助下,完成SecurityFitlerChain的构建

FilterChainProxy的构造

FilterChainProxy是通过WebSecurity`构造出来的

public final class WebSecurity extends
		AbstractConfiguredSecurityBuilder<Filter, WebSecurity> implements
		SecurityBuilder<Filter>, ApplicationContextAware {
// 持有所有的FilterChain		
private final List<SecurityBuilder<? extends SecurityFilterChain>> securityFilterChainBuilders = new ArrayList<SecurityBuilder<? extends SecurityFilterChain>>();

//将所有的FilterChain通过FilterChainProxy组织起来
protected Filter performBuild() throws Exception {
		int chainSize = ignoredRequests.size() + securityFilterChainBuilders.size();
		List<SecurityFilterChain> securityFilterChains = new ArrayList<SecurityFilterChain>(
				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;
		}
		postBuildAction.run();
		return result;
	}

本节只是简单讲了Spring Filter是如何组织起来,处理请求的,接下来聊聊具体到1个Filter中的关键点

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值