spring security配置构建分析

先看一张大图
在这里插入图片描述
从官网给的图中我们可以知道启动是通过封装一个FilterChainProxy 到servlet的filter体系中,来完成安全配置的全套操作。记住这个点,先放着,接着我们来了解spring security 配置模块中几个顶层接口

  • org.springframework.security.config.annotation.SecurityBuilder
  • org.springframework.security.config.annotation.SecurityConfigurer
  • org.springframework.security.config.annotation.ObjectPostProcessor
    首先我们先看SecurityBuilder这个接口,他有一个抽象实现AbstractSecurityBuilder 再来一个扩展抽象实现类AbstractConfiguredSecurityBuilder;类图如下
    在这里插入图片描述
    在顶层接口中只有一个方法
O build() throws Exception;

AbstractSecurityBuilder中新增了两个方法并抽象了上层接口的方法

//安全构造对象
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

public abstract class AbstractConfiguredSecurityBuilder<O, B extends SecurityBuilder<O>>
		extends AbstractSecurityBuilder<O> {
	private final Log logger = LogFactory.getLog(getClass());
	//	初始化需要构造的配置类容器配置类都是SecurityConfigurer的子类
	private final LinkedHashMap<Class<? extends SecurityConfigurer<O, B>>, List<SecurityConfigurer<O, B>>> configurers = new LinkedHashMap<Class<? extends SecurityConfigurer<O, B>>, List<SecurityConfigurer<O, B>>>();
	private final List<SecurityConfigurer<O, B>> configurersAddedInInitializing = new ArrayList<SecurityConfigurer<O, B>>();

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

	private final boolean allowConfigurersOfSameType;

	private BuildState buildState = BuildState.UNBUILT;
	
	private ObjectPostProcessor<Object> objectPostProcessor;

	//构造函数传入需要被spring容器后置处理器处理的对象
	protected AbstractConfiguredSecurityBuilder(
			ObjectPostProcessor<Object> objectPostProcessor) {
		this(objectPostProcessor, false);
	}

	//构造函数,判断在postProcess阶段是被被允许操作的一些行为,例如是否覆盖还是多个配置。
	protected AbstractConfiguredSecurityBuilder(
			ObjectPostProcessor<Object> objectPostProcessor,
			boolean allowConfigurersOfSameType) {
		Assert.notNull(objectPostProcessor, "objectPostProcessor cannot be null");
		this.objectPostProcessor = objectPostProcessor;
		this.allowConfigurersOfSameType = allowConfigurersOfSameType;
	}

	//通过推断获取还是构建对象。
	public O getOrBuild() {
		if (isUnbuilt()) {
			try {
				return build();
			}
			catch (Exception e) {
				logger.debug("Failed to perform build. Returning null", e);
				return null;
			}
		}
		else {
			return getObject();
		}
	}

	//传入需要被构建的 配置类,即上面描述的 SecurityConfigurer的所有子类
	//在构建前先到spring ioc容器中过一轮postProcessor的操作,
	//configurer.addObjectPostProcessor这里也就意味着我们可以任意变更
	//已经配置好的所有filter环节。
	@SuppressWarnings("unchecked")
	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;
	}

	//保存配置对象用于共享
	@SuppressWarnings("unchecked")
	public <C> void setSharedObject(Class<C> sharedType, C object) {
		this.sharedObjects.put(sharedType, object);
	}

	//获取共享对像
	@SuppressWarnings("unchecked")
	public <C> C getSharedObject(Class<C> sharedType) {
		return (C) this.sharedObjects.get(sharedType);
	}

	//获取所有共享对象
	public Map<Class<? extends Object>, Object> getSharedObjects() {
		return Collections.unmodifiableMap(this.sharedObjects);
	}

	//将配置类对象缓存,确保需要时可以随时取到,开头的配置池
	@SuppressWarnings("unchecked")
	private <C extends SecurityConfigurer<O, B>> void add(C configurer) throws Exception {
		Assert.notNull(configurer, "configurer cannot be null");

		Class<? extends SecurityConfigurer<O, B>> clazz = (Class<? extends SecurityConfigurer<O, B>>) configurer
				.getClass();
		synchronized (configurers) {
			if (buildState.isConfigured()) {
				throw new IllegalStateException("Cannot apply " + configurer
						+ " to already built object");
			}
			List<SecurityConfigurer<O, B>> configs = allowConfigurersOfSameType ? this.configurers
					.get(clazz) : null;
			if (configs == null) {
				configs = new ArrayList<SecurityConfigurer<O, B>>(1);
			}
			configs.add(configurer);
			this.configurers.put(clazz, configs);
			if (buildState.isInitializing()) {
				this.configurersAddedInInitializing.add(configurer);
			}
		}
	}

	//获取缓存的所有配置对象
	@SuppressWarnings("unchecked")
	public <C extends SecurityConfigurer<O, B>> List<C> getConfigurers(Class<C> clazz) {
		List<C> configs = (List<C>) this.configurers.get(clazz);
		if (configs == null) {
			return new ArrayList<>();
		}
		return new ArrayList<>(configs);
	}

	//移除所有配置对象
	@SuppressWarnings("unchecked")
	public <C extends SecurityConfigurer<O, B>> List<C> removeConfigurers(Class<C> clazz) {
		List<C> configs = (List<C>) this.configurers.remove(clazz);
		if (configs == null) {
			return new ArrayList<>();
		}
		return new ArrayList<>(configs);
	}

	//根据类名获取配置对象
	@SuppressWarnings("unchecked")
	public <C extends SecurityConfigurer<O, B>> C getConfigurer(Class<C> clazz) {
		List<SecurityConfigurer<O, B>> configs = this.configurers.get(clazz);
		if (configs == null) {
			return null;
		}
		if (configs.size() != 1) {
			throw new IllegalStateException("Only one configurer expected for type "
					+ clazz + ", but got " + configs);
		}
		return (C) configs.get(0);
	}

	//根据类目移除配置对象
	@SuppressWarnings("unchecked")
	public <C extends SecurityConfigurer<O, B>> C removeConfigurer(Class<C> clazz) {
		List<SecurityConfigurer<O, B>> configs = this.configurers.remove(clazz);
		if (configs == null) {
			return null;
		}
		if (configs.size() != 1) {
			throw new IllegalStateException("Only one configurer expected for type "
					+ clazz + ", but got " + configs);
		}
		return (C) configs.get(0);
	}

	//指定使用的 ObjectPostProcessor
	@SuppressWarnings("unchecked")
	public O objectPostProcessor(ObjectPostProcessor<Object> objectPostProcessor) {
		Assert.notNull(objectPostProcessor, "objectPostProcessor cannot be null");
		this.objectPostProcessor = objectPostProcessor;
		return (O) this;
	}

	//执行postprocess操作,这里即调用了spring ioc容器的postprocess过程
	protected <P> P postProcess(P object) {
		return this.objectPostProcessor.postProcess(object);
	}

	//build 流程
	@Override
	protected final O doBuild() throws Exception {
		synchronized (configurers) {
			buildState = BuildState.INITIALIZING;
			//初始化前
			beforeInit();
			//初始化中
			init();

			buildState = BuildState.CONFIGURING;
			//配置前
			beforeConfigure();
			//配置中
			configure();

			buildState = BuildState.BUILDING;
			//执行build
			O result = performBuild();

			buildState = BuildState.BUILT;
			//返回被build的对象
			return result;
		}
	}

	//可扩展的调用周期
	protected void beforeInit() throws Exception {
	}

	//可扩展
	protected void beforeConfigure() throws Exception {
	}

	//留给子类扩展具体的build过程
	protected abstract O performBuild() throws Exception;
	//初始化过程,即执行所有SecurityConfigurer.init方法
	@SuppressWarnings("unchecked")
	private void init() throws Exception {
		Collection<SecurityConfigurer<O, B>> configurers = getConfigurers();
		
		for (SecurityConfigurer<O, B> configurer : configurers) {
			configurer.init((B) this);
		}

		for (SecurityConfigurer<O, B> configurer : configurersAddedInInitializing) {
			configurer.init((B) this);
		}
	}
	//配置过程
	@SuppressWarnings("unchecked")
	private void configure() throws Exception {
		Collection<SecurityConfigurer<O, B>> configurers = getConfigurers();

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

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

	//推断是否已经build
	private boolean isUnbuilt() {
		synchronized (configurers) {
			return buildState == BuildState.UNBUILT;
		}
	}

	//build 状态
	private static enum BuildState {
		//未执行调用
		UNBUILT(0),
		//初始化方法被执行
		INITIALIZING(1),
		//配置方法被执行
		CONFIGURING(2),
		//构造中
		BUILDING(3),
		//完成构造
		BUILT(4);

		private final int order;

		BuildState(int order) {
			this.order = order;
		}

		public boolean isInitializing() {
			return INITIALIZING.order == order;
		}

		//根据order判断配置顺序
		public boolean isConfigured() {
			return order >= CONFIGURING.order;
		}
	}
}

继承至AbstractConfiguredSecurityBuilder三个类如下

  • org.springframework.security.config.annotation.web.builders.HttpSecurity
  • org.springframework.security.config.annotation.web.builders.WebSecurity
  • org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder
    这三个类即为spring构建全部配置的主类
    最开始的三个顶层接口,派生出两个子类即
  • org.springframework.security.config.annotation.web.HttpSecurityBuilder
  • org.springframework.security.config.annotation.web.WebSecurityConfigurer
    这两个类则为spring配置上面三个类的顶层入口。以上三个类同样组装实现了这个接口HttpSecurityBuilder。而WebSecurity 极其子类则将被组装进该builder进行构建。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值