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