Skip to content

Commit f5fe9c0

Browse files
committed
更新SpringSecurity
1 parent 407abb3 commit f5fe9c0

3 files changed

+163
-16
lines changed

note/SpringSecurity/从零开始系统学习SpringSecurity和OAuth2(一)—— 初识SpringSecurity.md

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,21 @@
1-
@[toc]
1+
<!-- TOC -->
2+
- [前言](#前言)
3+
- [正文](#正文)
4+
- [1. 初识SpringSecurity](#1-初识springsecurity)
5+
- [2. Spring Security项目核心jar包介绍](#2-spring-security项目核心jar包介绍)
6+
- [3. SpringSecurity核心注解](#3-springsecurity核心注解)
7+
- [3.1 @EnableWebSecurity](#31-enablewebsecurity)
8+
- [3.2 @EnableGlobalAuthentication](#32-enableglobalauthentication)
9+
- [3.3 @EnableGlobalMethodSecurity](#33-enableglobalmethodsecurity)
10+
- [4. SpringSecurity核心组件](#4-springsecurity核心组件)
11+
- [4.1 认证](#41-认证)
12+
- [4.2 授权](#42-授权)
13+
- [5. SpringSecurity中的Filter](#5-springsecurity中的filter)
14+
- [5.1 FilterChainProxy以及其内部的Filter](#51-filterchainproxy以及其内部的filter)
15+
- [总结](#总结)
16+
- [参考](#参考)
17+
- [相关文章](#相关文章)
18+
<!-- /TOC -->
219
## 前言
320
相信了解过SpringSecurity或者是OAuth2的读者,会发现网上会有非常多的相关文章,或是纯概念的,或是带有demo的,无论是哪种类型的文章,本人去阅读之后,对于整个框架的概念还是一知半解,也仅仅是实现了某些功能、某些效果而已,若遇到某些问题时无从下手,只能去百度去Google。这是因为对于SpringSecurity和OAuth2的知识没有一个整体概念的把握,知识体系没有形成系统,遂决定写一个关于SpringSecurity和OAuth2的系列专栏,在构建自己知识体系的同时还希望能帮助有同样困惑的同学。
421

@@ -167,4 +184,5 @@ int vote(Authentication authentication, S object,
167184
- [《Spring Security Reference》](https://docs.spring.io/spring-security/site/docs/current/reference/html5/#preface)
168185

169186
## 相关文章
170-
- [从零开始系统学习SpringSecurity和OAuth2(二)—— 安全过滤器FilterChainProxy](https://blog.csdn.net/CoderBruis/article/details/107604400)
187+
- [从零开始系统学习SpringSecurity和OAuth2(二)—— 安全过滤器FilterChainProxy](https://github.com/coderbruis/JavaSourceCodeLearning/blob/master/note/SpringSecurity/%E4%BB%8E%E9%9B%B6%E5%BC%80%E5%A7%8B%E7%B3%BB%E7%BB%9F%E5%AD%A6%E4%B9%A0SpringSecurity%E5%92%8COAuth2%EF%BC%88%E4%BA%8C%EF%BC%89%E2%80%94%E2%80%94%20%E5%AE%89%E5%85%A8%E8%BF%87%E6%BB%A4%E5%99%A8FilterChainProxy.md)
188+
系统学习SpringSecurity和OAuth2(三)—— WebSecurity建造核心逻辑](https://github.com/coderbruis/JavaSourceCodeLearning/blob/master/note/SpringSecurity/%E4%BB%8E%E9%9B%B6%E5%BC%80%E5%A7%8B%E7%B3%BB%E7%BB%9F%E5%AD%A6%E4%B9%A0SpringSecurity%E5%92%8COAuth2%EF%BC%88%E4%B8%89%EF%BC%89%E2%80%94%E2%80%94%20WebSecurity%E5%BB%BA%E9%80%A0%E6%A0%B8%E5%BF%83%E9%80%BB%E8%BE%91.md- [从零开始)

note/SpringSecurity/从零开始系统学习SpringSecurity和OAuth2(三)—— WebSecurity建造核心逻辑.md

Lines changed: 127 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,12 @@
1-
@[toc]
1+
<!-- TOC -->
2+
- [前言](#前言)
3+
- [正文](#正文)
4+
- [1. AbstractConfiguredSecurityBuilder中安全配置类](#1-abstractconfiguredsecuritybuilder中安全配置类)
5+
- [2. AbstractConfiguredSecurityBuilder的doBuild()方法](#2-abstractconfiguredsecuritybuilder的dobuild方法)
6+
- [3. WebSecurity中的performBuild()方法](#3-websecurity中的performbuild方法)
7+
- [总结](#总结)
8+
- [相关文章](#相关文章)
9+
<!-- /TOC -->
210
## 前言
311
相信了解过SpringSecurity或者是OAuth2的读者,会发现网上会有非常多的相关文章,或是纯概念的,或是带有demo的,无论是哪种类型的文章,本人去阅读之后,对于整个框架的概念还是一知半解,也仅仅是实现了某些功能、某些效果而已,若遇到某些问题时无从下手,只能去百度去Google。这是因为对于SpringSecurity和OAuth2的知识没有一个整体概念的把握,知识体系没有形成系统,遂决定写一个关于SpringSecurity和OAuth2的系列专栏,在建造自己知识体系的同时还希望能帮助有同样困惑的同学。
412

@@ -9,7 +17,7 @@
917
## 正文
1018

1119
### 1. AbstractConfiguredSecurityBuilder中安全配置类
12-
SpringSecurity通过SecurityConfigurer来构建FilterChainProxy,构建前还需要进行配置。因此AbstractConfiguredSecurityBuilder还需要注入配置组件SecurityConfigurer,初始化配置组件SecurityConfigurer,调用SecurityConfigurer的configure方法。
20+
SpringSecurity通过SecurityConfigurer来建造FilterChainProxy,建造前还需要进行配置。因此AbstractConfiguredSecurityBuilder还需要注入配置组件SecurityConfigurer,初始化配置组件SecurityConfigurer,调用SecurityConfigurer的configure方法。
1321

1422
在AbstractConfiguredSecurityBuilder类中,看下安全配置类的定义:‘
1523

@@ -28,7 +36,7 @@ private final LinkedHashMap<Class<? extends SecurityConfigurer<O, B>>, List<Secu
2836
.getClass();
2937
// 同步去操作安全配置类集合
3038
synchronized (configurers) {
31-
// 查看构建状态是否是已经配置
39+
// 查看建造状态是否是已经配置
3240
if (buildState.isConfigured()) {
3341
throw new IllegalStateException("Cannot apply " + configurer
3442
+ " to already built object");
@@ -62,7 +70,7 @@ private final LinkedHashMap<Class<? extends SecurityConfigurer<O, B>>, List<Secu
6270
throws Exception {
6371
// 传入objectPostProcessor,该对象用于创建各种“实例”,具体什么作用下问会讲解,请留意
6472
configurer.addObjectPostProcessor(objectPostProcessor);
65-
// 将当前对象设置为构建者
73+
// 将当前对象设置为建造者
6674
configurer.setBuilder((B) this);
6775
// 调用add方法,向configurers集合中添加configurer
6876
add(configurer);
@@ -128,35 +136,35 @@ getOrApply方法主要是从configurers集合中获取配置类,如果存在
128136
到此处,安全配置类的作用已经提现出来了,就是向sharedObject中添加过滤器,并最终注入到FilterChainProxy中。
129137

130138
### 2. AbstractConfiguredSecurityBuilder的doBuild()方法
131-
随着configurers集合元素的注入,下面就是进行构建工作,调用doBuild()方法。
139+
随着configurers集合元素的注入,下面就是进行建造工作,调用doBuild()方法。
132140

133141
```
134142
@Override
135143
protected final O doBuild() throws Exception {
136144
synchronized (configurers) {
137-
// 设置构建状态为初始化中
145+
// 设置建造状态为初始化中
138146
buildState = BuildState.INITIALIZING;
139147
140148
// 进行初始化前的工作
141149
beforeInit();
142150
// 初始化
143151
init();
144152
145-
// 设置构建状态为配置中
153+
// 设置建造状态为配置中
146154
buildState = BuildState.CONFIGURING;
147155
148156
// 配置前的工作
149157
beforeConfigure();
150158
// 调用配置
151159
configure();
152160
153-
// 设置构建状态为构建中
161+
// 设置建造状态为建造中
154162
buildState = BuildState.BUILDING;
155163
156-
// 执行构建核心逻辑
164+
// 执行建造核心逻辑
157165
O result = performBuild();
158166
159-
// 设置构建状态为已构建
167+
// 设置建造状态为已建造
160168
buildState = BuildState.BUILT;
161169
162170
return result;
@@ -188,6 +196,113 @@ beforeInit()和beforeConfigure()是一个空方法体,没有逻辑。
188196
}
189197
```
190198

191-
这需要注意的是,init和configure方法是有接口SecurityConfigurer接口定义的,但其实现以由SecurityConfigurerAdapter这个抽象的适配器类实现了,所以最终的安全配置类可重写init()和configure(),也可以不重写。所以可以发现,很多安全配置类是重写没有init()方法的。
199+
这需要注意的是,init和configure方法是有接口SecurityConfigurer接口定义的,但其实现以由SecurityConfigurerAdapter这个抽象的适配器类实现了,所以最终的安全配置类可重写init()和configure(),也可以不重写。所以可以发现,很多安全配置类是没有重写init()方法的。
192200

193-
未完待续....
201+
202+
**接着就是configure()方法的调用**
203+
204+
```
205+
private void configure() throws Exception {
206+
// 调用getConfigurers()方法获取this.configurers的所有value值,并以List集合的形式返回
207+
Collection<SecurityConfigurer<O, B>> configurers = getConfigurers();
208+
209+
for (SecurityConfigurer<O, B> configurer : configurers) {
210+
// 遍历configurers,然后依次调用其configure方法
211+
configurer.configure((B) this);
212+
}
213+
}
214+
```
215+
216+
在前面已经已经以ExpressionUrlAuthorizationConfigurer为例,去查看安全配置类configure方法的作用,都知道安全配置类的configure方法是用于将过滤器添加到sharedObject缓存中。
217+
218+
经过init()和configure()方法的执行,以及可以开始进行建造工作了,因而调用performBuild()方法执行建造过程。
219+
220+
```
221+
protected abstract O performBuild() throws Exception;
222+
```
223+
可以看到在AbstractConfiguredSecurityBuilder中,performBuild是以抽象方法的形式存在的,所以实现逻辑都在其子类中。
224+
225+
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200810112226524.png)
226+
227+
这里HttpSecurity和WebSecurity类名这么像,有什么异同呢?
228+
229+
> HttpSecurity
230+
231+
HttpSecurity允许为特定的http请求配置基于Web的安全特性。默认情况下,HttpSecurity将应用于所有请求,但是如果需要限制请求,则可以通过RequestMatcher或其他类似方法来进行限制。
232+
233+
> WebSecurity
234+
235+
而WebSecurity是通过WebSecurityConfiguration创建的,用于去创建类FilterChainProxy。在SpringSecurity中,WebSecurity通过HttpSecurity来对某些请求进行拦截限制。
236+
237+
> 区别
238+
239+
WebSecurity用于建造FilterChainProxy,WebSecurity是包含HttpSecurity的一个更大的概念,而HttpSecurity仅是用于建造FilterChainProxy中的一个SecurityFilterChain。
240+
241+
242+
### 3. WebSecurity中的performBuild()方法
243+
WebSecurity重写了AbstractConfiguredSecurityBuilder的perfomBuild()方法,核心逻辑如下:
244+
245+
```
246+
@Override
247+
protected Filter performBuild() throws Exception {
248+
Assert.state(
249+
!securityFilterChainBuilders.isEmpty(),
250+
() -> "At least one SecurityBuilder<? extends SecurityFilterChain> needs to be specified. "
251+
+ "Typically this done by adding a @Configuration that extends WebSecurityConfigurerAdapter. "
252+
+ "More advanced users can invoke "
253+
+ WebSecurity.class.getSimpleName()
254+
+ ".addSecurityFilterChainBuilder directly");
255+
// 获取chain大小
256+
int chainSize = ignoredRequests.size() + securityFilterChainBuilders.size();
257+
// 设置安全过滤器链集合
258+
List<SecurityFilterChain> securityFilterChains = new ArrayList<>(
259+
chainSize);
260+
// 遍历igoredRequests集合,该集合表示存储着忽略拦截的请求
261+
for (RequestMatcher ignoredRequest : ignoredRequests) {
262+
securityFilterChains.add(new DefaultSecurityFilterChain(ignoredRequest));
263+
}
264+
for (SecurityBuilder<? extends SecurityFilterChain> securityFilterChainBuilder : securityFilterChainBuilders) {
265+
// 先调用securityFilterChainBuilder执行build()方法,然后添加进securityFilterChains集合中。之列build()方法是去迭代执行doBuild()逻辑。
266+
securityFilterChains.add(securityFilterChainBuilder.build());
267+
}
268+
269+
// 创建一个FilterChainProxy对象,传入一个securityFilterChains对象
270+
FilterChainProxy filterChainProxy = new FilterChainProxy(securityFilterChains);
271+
if (httpFirewall != null) {
272+
// 设置http防火墙属性
273+
filterChainProxy.setFirewall(httpFirewall);
274+
}
275+
filterChainProxy.afterPropertiesSet();
276+
277+
Filter result = filterChainProxy;
278+
if (debugEnabled) {
279+
logger.warn("\n\n"
280+
+ "********************************************************************\n"
281+
+ "********** Security debugging is enabled. *************\n"
282+
+ "********** This may include sensitive information. *************\n"
283+
+ "********** Do not use in a production system! *************\n"
284+
+ "********************************************************************\n\n");
285+
result = new DebugFilter(filterChainProxy);
286+
}
287+
288+
// 执行一个线程
289+
postBuildAction.run();
290+
return result;
291+
}
292+
293+
```
294+
295+
在performBuild()方法中,会执行securityFilterChainBuilder的build()方法,该方法又会去迭代执行doBuild()方法,最终返回一个SecurityFilterChain对象。
296+
297+
298+
综上,本文对WebSecurity的建造逻辑进行了概括性的讲解,更加深入的内容还需要进行代码debug跟踪深入查看,这样才能加深对于WebSecurity的理解。
299+
300+
## 总结
301+
- 安全配置类是在HttpSecurity、XXConfigurerAdapter等类中进行添加
302+
- WebSecurity和HttpSecurity区别在于,WebSecurity是用于建造FilterChainProxy的,它是包含HttpSecurity;而HttpSecurity是用于对请求进行限制,同时还用于建造DefaultSecurityFilterChain
303+
- 安全配置类主要是通过configure方法向sharedObject缓存对象中添加过滤器,并最终添加进FilterChainProxy过滤器链中
304+
- WebSecurity建造FilterChainProxy的核心逻辑可以笼统的分为三步:安全配置了初始化、安全配置类configure的调用、performBuild的调用
305+
306+
## 相关文章
307+
- [从零开始系统学习SpringSecurity和OAuth2(一)—— 初识SpringSecurity](https://github.com/coderbruis/JavaSourceCodeLearning/blob/master/note/SpringSecurity/%E4%BB%8E%E9%9B%B6%E5%BC%80%E5%A7%8B%E7%B3%BB%E7%BB%9F%E5%AD%A6%E4%B9%A0SpringSecurity%E5%92%8COAuth2%EF%BC%88%E4%B8%80%EF%BC%89%E2%80%94%E2%80%94%20%E5%88%9D%E8%AF%86SpringSecurity.md)
308+
- [从零开始系统学习SpringSecurity和OAuth2(二)—— 安全过滤器FilterChainProxy](https://github.com/coderbruis/JavaSourceCodeLearning/blob/master/note/SpringSecurity/%E4%BB%8E%E9%9B%B6%E5%BC%80%E5%A7%8B%E7%B3%BB%E7%BB%9F%E5%AD%A6%E4%B9%A0SpringSecurity%E5%92%8COAuth2%EF%BC%88%E4%BA%8C%EF%BC%89%E2%80%94%E2%80%94%20%E5%AE%89%E5%85%A8%E8%BF%87%E6%BB%A4%E5%99%A8FilterChainProxy.md)

note/SpringSecurity/从零开始系统学习SpringSecurity和OAuth2(二)—— 安全过滤器FilterChainProxy.md

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,17 @@
1-
@[toc]
1+
<!-- TOC -->- [前言](#前言)
2+
- [正文](#正文)
3+
- [1. FilterChainProxy什么时候注入Spring容器中的](#1--filterchainproxy什么时候注入spring容器中的)
4+
- [2. WebSecurityConfiguration类](#2-websecurityconfiguration类)
5+
- [3. WebSecurity类](#3-websecurity类)
6+
- [4. AbstractConfiguredSecurityBuilder类](#4-abstractconfiguredsecuritybuilder类)
7+
- [5. SecurityConfigurer类](#5-securityconfigurer类)
8+
- [6. doBuild()方法](#6-dobuild方法)
9+
- [7. WebSecurity什么时候被创建的?](#7-websecurity什么时候被创建的)
10+
- [总结](#总结)
11+
- [参考](#参考)
12+
- [相关文章](#相关文章)
13+
14+
<!-- /TOC -->
215
## 前言
316
相信了解过SpringSecurity或者是OAuth2的读者,会发现网上会有非常多的相关文章,或是纯概念的,或是带有demo的,无论是哪种类型的文章,本人去阅读之后,对于整个框架的概念还是一知半解,也仅仅是实现了某些功能、某些效果而已,若遇到某些问题时无从下手,只能去百度去Google。这是因为对于SpringSecurity和OAuth2的知识没有一个整体概念的把握,知识体系没有形成系统,遂决定写一个关于SpringSecurity和OAuth2的系列专栏,在建造自己知识体系的同时还希望能帮助有同样困惑的同学。
417

@@ -356,4 +369,5 @@ performBuild()方法是AbstractConfiguredSecurityBuilder提供的抽象方法,
356369
- [深入浅出Spring Security(一):三句话解释框架原理](https://blog.csdn.net/zimou5581/article/details/102457672)
357370

358371
## 相关文章
359-
- [从零开始系统学习SpringSecurity和OAuth2(一)—— 初识SpringSecurity](https://blog.csdn.net/CoderBruis/article/details/107297547)
372+
- [从零开始系统学习SpringSecurity和OAuth2(一)—— 初识SpringSecurity](https://github.com/coderbruis/JavaSourceCodeLearning/blob/master/note/SpringSecurity/%E4%BB%8E%E9%9B%B6%E5%BC%80%E5%A7%8B%E7%B3%BB%E7%BB%9F%E5%AD%A6%E4%B9%A0SpringSecurity%E5%92%8COAuth2%EF%BC%88%E4%B8%80%EF%BC%89%E2%80%94%E2%80%94%20%E5%88%9D%E8%AF%86SpringSecurity.md)
373+
- [从零开始系统学习SpringSecurity和OAuth2(三)—— WebSecurity建造核心逻辑](https://github.com/coderbruis/JavaSourceCodeLearning/blob/master/note/SpringSecurity/%E4%BB%8E%E9%9B%B6%E5%BC%80%E5%A7%8B%E7%B3%BB%E7%BB%9F%E5%AD%A6%E4%B9%A0SpringSecurity%E5%92%8COAuth2%EF%BC%88%E4%B8%89%EF%BC%89%E2%80%94%E2%80%94%20WebSecurity%E5%BB%BA%E9%80%A0%E6%A0%B8%E5%BF%83%E9%80%BB%E8%BE%91.md)

0 commit comments

Comments
 (0)