官网地址 Spring Security Reference
版本:Version 5.5.0
WebSecurity 的继承关系图
在前面了解过 WebSecurity、HttpSecurity、AuthenticationManagerBuilder 这三个重要构建者公共的部分:
|- SecurityBuilder
|- AbstractSecurityBuilder
|- AbstractConfiguredSecurityBuilder
公共的这部分对构建者做扩展,点击这里可以回顾一下,这里主要看看 WebSecurity 类。
Aware 和 ApplicationContextAware
当一个类时限了 Aware 接口时,Spring 框架就会赋予它一种感知力。比如 ApplicationContextAware ,它有一个方法发:
void setApplicationContext(ApplicationContext var1) throws BeansException;
Spring容器在实例化对应的 Bean 时,通过实现 Aware 就能够感知到当前实例化的 Bean 需要什么东西,这里实现 ApplicationContextAware 接口,Spring 容器就能感知到这个 Bean 需要 Spring 容器上下文实例,并在创建 Bean 对象的后置处理中把这个实例注入其中。
大概逻辑:创建Bean时会调用 invokeAwareInterfaces(Object bean) 方法,这里会判断当前 Bean 是不是 Aware,在往下细分了很对种特殊的 ***Aware,这些 ***Aware 都需要注入 applicationContext 。
【这里的描述是用 ApplicationContextAwareProcessor 为例作为解释的,详细可以看源码。】
WebSecurity
WebSecurity 构建器是来创建一个Web过滤器的。
内部类
- IgnoredRequestConfigurer
允许注册应该被 Spring Security 忽略的 RequestMatcher 实例。 - MvcMatchersIgnoredRequestConfigurer
一个 WebSecurity.IgnoredRequestConfigurer(说明继承关系),允许有选择地配置 MvcRequestMatcher.setMethod(HttpMethod)
MvcMatchersIgnoredRequestConfigurer 是 IgnoredRequestConfigurer 的子类。可以把它们看作是一个请求匹配注册表,当接受到请求时他们会与请求信息做匹配,根据匹配结果做出响应的操作。
成员变量
- ignoredRequests
这是一个 List<RequestMatcher> 集合,用于存储将要被Spring Security 忽略的请求的请求匹配器。 - securityFilterChainBuilders
也是一个 List 集合,用于存放 SecurityFilterChain 过滤器链的构造器。List<SecurityBuilder<? extends SecurityFilterChain>>
- ignoredRequestRegistry
这是一个忽略请求注册表,所有将要忽略的请求都注册到这里注册表中。 - filterSecurityInterceptor
FilterSecurityInterceptor 拦截器 - httpFirewall
字面理解就是 Http 防火墙,猜测它的功能应该也是拦截 http 请求的 - privilegeEvaluator
- defaultWebSecurityExpressionHandler
默认的 WebSecurityExpressionHandler (Web安全表达式处理器) - expressionHandler
表达式处理器
后面几个成员变量暂时没有理解,后面理解了再做补充。这里主要理解 WebSecurity 的工作内容,其他细节暂时先不要过于钻牛角尖。等对整个框架有了宏观的认识之后,应用到具体项目的时候再结合实践去看,应该就容易理解了。
构造函数
略。就是 super(objectPostProcessor);
,父类 AbstractConfiguredSecurityBuilder 的构造器。
performBuild 方法
构建对象的具体实现方法。通过源码可以看出 WebSecurity 实际上构建的是一个 FilterChainProxy (过滤器链代理) 对象。
@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;
}
主要完成了:
-
断言:securityFilterChainBuilders 非空
-
创建一个集合 Lis\t<SecurityFilterChain> securityFilterChains,存放过滤器链的集合
过滤器链的来源有两个:- ignoredRequest
通过将要忽略的 ignoredRequest 构建一个默认过滤器链,每一个请求路径都会创建一个过滤器,这些过滤器组成一个过滤器链。ignoredRequest 从哪里来的再后面的方法中可以看到。
- securityFilterChainBuilders
根据 securityFilterChainBuilders 中的构建器调用 build 方法构建出来,每一个构建器都会构建出一个过滤器链。关于 securityFilterChainBuilders 中构建器的来源是通过 WebSecurity 的 addSecurityFilterChainBuilder 方法添加的。
- ignoredRequest
-
创建 FilterChainProxy 对象。
-
如果 httpFirewall 不为空就设置 FilterChainProxy 的 firewall 属性。
-
返回构建好的 FilterChainProxy 对象。
setApplicationContext 方法
通过实现了 ApplicationContextAware 接口,再创建 WebSecurity 对象时会触发这个方法,并注入 ApplicationContext 实例。这个方法中做了一些初始的设置。
ignoring 方法
public IgnoredRequestConfigurer ignoring() {
return ignoredRequestRegistry;
}
返回 ignoredRequestRegistry 实例,便于配置。
这个内部类还有一个 and 方法,这个方法会返回当前的 WebSecurity 实例,方便继续做自定义配置。
其他方法
- addSecurityFilterChainBuilder 方法
添加 SecurityFilterChainBuilder 到 securityFilterChainBuilders 链表 - httpFirewall 方法
设置 httpFirewall 属性 - debug 方法
设置 debugEnabled 属性,标记调试模式开启状态 - expressionHandler 方法
设置 expressionHandler 属性 - securityInterceptor 方法
设置 filterSecurityInterceptor 属性 - postBuildAction 方法
设置后置处理器对象
这些 方法都是之间传入响应的类的对象实例来完成对 WebSecurity 的属性设置,并且再设置完成后都会立刻返回 WebSecurity 实例,方便后期的设置。
总结
构建 FilterChainProxy (过滤器链代理) 对象实例。