首页 > 数据库 > 数据库开发技术 > SpringSecurity 安全对象的构建
securityConfigurer是用来配置SecurityBuilder的。init设置一些共享状态,configure设置属性。典型的有FormLoginConfigurer、CsrfConfigurer等等
public interface SecurityConfigurer<O, B extends SecurityBuilder<O>> {
void init(B builder) throws Exception;
void configure(B builder) throws Exception;
SecurityConfigurerAdapter:实现了SecurityConfigurer适配了接口方法。提供了配置的扩展(ObjectPostProcessor)以及链式调用的方式。
public abstract class SecurityConfigurerAdapter<O, B extends SecurityBuilder<O>> implements SecurityConfigurer<O, B> {
// 构建对象
private B securityBuilder;
// 提供了配置扩展方式
private CompositeObjectPostProcessor objectPostProcessor = new CompositeObjectPostProcessor();
// 提供了链式调用方式,获取构建对象
public B and() {
return getBuilder();
}
// SecurityConfigurer 父类方法的适配
@Override
public void init(B builder) throws Exception {
}
@Override
public void configure(B builder) throws Exception {
}
}
AbstractHttpConfigurer:继承SecurityConfigurerAdapter提供了移除配置以及添加ObjectPostProcessor扩展对象
public abstract class AbstractHttpConfigurer<T extends AbstractHttpConfigurer<T, B>, B extends HttpSecurityBuilder<B>>
extends SecurityConfigurerAdapter<DefaultSecurityFilterChain, B> {
public B disable() {
getBuilder().removeConfigurer(getClass());
return getBuilder();
}
@SuppressWarnings("unchecked")
public T withObjectPostProcessor(ObjectPostProcessor<?> objectPostProcessor) {
addObjectPostProcessor(objectPostProcessor);
return (T) this;
}
}
AbstractConfiguredSecurityBuilder
AbstractSecurityBuilder(父类):提供了CAS的方式构建一个对象。确保对象只能被构建一次。
AbstractConfiguredSecurityBuilder:添加构建当前对象的SecurityConfigurer、提供模板方法的方式构建当前对象、设置共享对象等等
public abstract class AbstractConfiguredSecurityBuilder<O, B extends SecurityBuilder<O>>
extends AbstractSecurityBuilder<O> {
// 设置共享对象
private final Map<Class<?>, Object> sharedObjects = new HashMap<>();
// SecurityConfigurer 用来构建 SecurityBuilder
private final LinkedHashMap<Class<? extends SecurityConfigurer<O, B>>, List<SecurityConfigurer<O, B>>> configurers = new LinkedHashMap<>();
// 对象的构建状态
private BuildState buildState = BuildState.UNBUILT;
// 对安全对象的扩展
private ObjectPostProcessor<Object> objectPostProcessor;
// 添加 SecurityConfigure 配置
private <C extends SecurityConfigurer<O, B>> void add(C configurer) {
Class<? extends SecurityConfigurer<O, B>> clazz = (Class<? extends SecurityConfigurer<O, B>>) configurer.getClass();
synchronized (this.configurers) {
if (this.buildState.isConfigured()) {
throw new IllegalStateException("Cannot apply " + configurer + " to already built object");
}
List<SecurityConfigurer<O, B>> configs = null;
if (this.allowConfigurersOfSameType) {
configs = this.configurers.get(clazz);
}
configs = (configs != null) ? configs : new ArrayList<>(1);
configs.add(configurer);
this.configurers.put(clazz, configs);
// 为何要在初始化时再次将configurer加入集合?
// 因为当当前对象的构建状态为init时,就会执行configurers中所有的config的init方法。而在执行init方法时又会再次添加其他的configurer,此时添加的configurer也会添加到configurersAddedInInitializing,当执行完init初始化方法后,也需要再次对configurersAddedInInitializing中的configurer执行init
if (this.buildState.isInitializing()) {
this.configurersAddedInInitializing.add(configurer);
}
}
}
/**
* 采用模板、通过SecurityConfigurer执行构建指定对象
*/
protected final O doBuild() throws Exception {
synchronized (this.configurers) {
this.buildState = BuildState.INITIALIZING;
beforeInit();
init();
this.buildState = BuildState.CONFIGURING;
beforeConfigure();
configure();
this.buildState = BuildState.BUILDING;
O result = performBuild();
this.buildState = BuildState.BUILT;
return result;
}
}
}
欢迎加入 DevXTalk 的技术交流群,在这里你可以和大佬们一起交流分享技术,行业经验,提升自我。
结识新的业内朋友,扩大自己的圈子,当你想换工作的时候也许就能拿到不错的 offer 。总之期待你的加入...
「看完本文有收获?转发给更多的朋友吧」
「DevXTalk 不止于技术」
原文作者:DevXTalk;如有侵权,请联系管理员删除。