docs: update

pull/177/head
Libin YANG 5 months ago
parent bee198f4cc
commit 464d7b5c0f

@ -118,10 +118,6 @@
- [SpringBoot 日志系统](/docs/SpringBoot/SpringBoot-LogSystem.md) - [SpringBoot 日志系统](/docs/SpringBoot/SpringBoot-LogSystem.md)
- [SpringBoot ConditionalOnBean](/docs/SpringBoot/SpringBoot-ConditionalOnBean.md) - [SpringBoot ConditionalOnBean](/docs/SpringBoot/SpringBoot-ConditionalOnBean.md)
### SpringBootBatch
- [SpringBootBatch 源码](/docs/SpringBootBatch/SpringBootBatch源码.md)
### Spring Cloud ### Spring Cloud
- [Spring Cloud Commons 源码](docs/SpringCloud/spring-cloud-commons-source-note.md) - [Spring Cloud Commons 源码](docs/SpringCloud/spring-cloud-commons-source-note.md)

@ -171,13 +171,6 @@ export default defineConfig({
{ text: 'SpringBoot ConditionalOnBean', link: '/SpringBoot/SpringBoot-ConditionalOnBean' }, { text: 'SpringBoot ConditionalOnBean', link: '/SpringBoot/SpringBoot-ConditionalOnBean' },
], ],
}, },
// {
// text: 'SpringBootBatch',
// collapsed: true,
// items: [
// { text: 'SpringBootBatch 源码', link: '/SpringBootBatch/SpringBootBatch源码' },
// ],
// },
{ {
text: 'Spring Cloud', text: 'Spring Cloud',
collapsed: true, collapsed: true,

File diff suppressed because it is too large Load Diff

@ -11,7 +11,7 @@
我们每次添加 `<artifactId>spring-boot-starter-security</artifactId>`,启动的时候会有一条类似的日志: 我们每次添加 `<artifactId>spring-boot-starter-security</artifactId>`,启动的时候会有一条类似的日志:
``` ```txt
Using generated springSecurity password: 1db8eb87-e2ee-4c72-88e7-9b85268c4430 Using generated springSecurity password: 1db8eb87-e2ee-4c72-88e7-9b85268c4430
This generated password is for development use only. Your springSecurity configuration must be updated before running your This generated password is for development use only. Your springSecurity configuration must be updated before running your
@ -20,9 +20,9 @@ application in production.
找到 `UserDetailsServiceAutoConfiguration#InMemoryUserDetailsManager` 类,它是 springboot 自动装配的。 找到 `UserDetailsServiceAutoConfiguration#InMemoryUserDetailsManager` 类,它是 springboot 自动装配的。
下面这些都是 springboot 自动装配类,在 `spring-boot-autoconfigure-2.7.7.jar` > META-INF > spring > org.springframework.boot.autoconfigure.AutoConfiguration.imports 中。这些类就是 Spring Security 的全部了。 下面这些都是 springboot 自动装配类
```imports ```java
org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration
org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration
org.springframework.boot.autoconfigure.security.servlet.SecurityFilterAutoConfiguration org.springframework.boot.autoconfigure.security.servlet.SecurityFilterAutoConfiguration
@ -284,7 +284,7 @@ public @interface EnableWebSecurity {
### WebSecurityConfiguration ### WebSecurityConfiguration
首先先看类注释(以后都默认翻译成简体中文.ali 翻译): 首先先看类注释 (以后都默认翻译成简体中文 .ali 翻译):
使用 WebSecurity 创建执行 Spring 安全 web 安全的 FilterChainProxy。然后导出必要的 bean。 使用 WebSecurity 创建执行 Spring 安全 web 安全的 FilterChainProxy。然后导出必要的 bean。
可以通过实现 WebSecurityConfigurer WebSecurityConfigurer 并将其公开为 Configuration 或公开 WebSecurityCustomizer bean 来进行自定义。 可以通过实现 WebSecurityConfigurer WebSecurityConfigurer 并将其公开为 Configuration 或公开 WebSecurityCustomizer bean 来进行自定义。
@ -476,7 +476,7 @@ protected final O doBuild() throws Exception {
剩下的都是一些创建一些 bean 了。 剩下的都是一些创建一些 bean 了。
`SecurityExpressionHandler`: 默认为`DefaultWebSecurityExpressionHandler`类(Facade 将 springSecurity 评估安全表达式的要求与基础表达式对象的实现隔离) `SecurityExpressionHandler`: 默认为`DefaultWebSecurityExpressionHandler`类 (Facade 将 springSecurity 评估安全表达式的要求与基础表达式对象的实现隔离)
`WebInvocationPrivilegeEvaluator`: 为 `WebSecurity#performBuild()`中创建的 `requestMatcherPrivilegeEvaluatorsEntries` `WebInvocationPrivilegeEvaluator`: 为 `WebSecurity#performBuild()`中创建的 `requestMatcherPrivilegeEvaluatorsEntries`
使用`RequestMatcherDelegatingWebInvocationPrivilegeEvaluator`包装。(允许用户确定他们是否具有给定 web URI 的特权。) 使用`RequestMatcherDelegatingWebInvocationPrivilegeEvaluator`包装。(允许用户确定他们是否具有给定 web URI 的特权。)
@ -506,7 +506,7 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti
// 配置认证 // 配置认证
http.formLogin(); http.formLogin();
// 设置URL的授权问题 // 设置 URL 的授权问题
// 多个条件取交集 // 多个条件取交集
http.authorizeRequests() http.authorizeRequests()
// 匹配 / 控制器 permitAll() 不需要被认证就可以访问 // 匹配 / 控制器 permitAll() 不需要被认证就可以访问
@ -516,7 +516,7 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti
// anyRequest() 所有请求 authenticated() 必须被认证 // anyRequest() 所有请求 authenticated() 必须被认证
.anyRequest().authenticated(); .anyRequest().authenticated();
// .accessDecisionManager(accessDecisionManager()); // .accessDecisionManager(accessDecisionManager());
// 关闭csrf // 关闭 csrf
http.csrf().disable(); http.csrf().disable();
return http.build(); return http.build();
} }
@ -589,14 +589,14 @@ throw new IllegalArgumentException("The Filter class "+filter.getClass().getName
提示: 这个里面每次添加一个类,如果在`HttpSecurity`中调用`getOrApply` 提示: 这个里面每次添加一个类,如果在`HttpSecurity`中调用`getOrApply`
。比如这个代码调用的是`exceptionHandlingCustomizer.customize(getOrApply(new ExceptionHandlingConfigurer<>()));`。 。比如这个代码调用的是`exceptionHandlingCustomizer.customize(getOrApply(new ExceptionHandlingConfigurer<>()));`。
打开`ExceptionHandlingConfigurer`类,发现是一个`HttpSecurityBuilder` 这样只需要看`configure`方法大概就能明白这个是一个什么类。 打开`ExceptionHandlingConfigurer`类,发现是一个`HttpSecurityBuilder` 这样只需要看`configure`方法大概就能明白这个是一个什么类。
这个就是在 filter 中添加了一个`ExceptionTranslationFilter`filter.主要就是`SecurityConfigurer` 这个就是在 filter 中添加了一个`ExceptionTranslationFilter`filter. 主要就是`SecurityConfigurer`
的俩个方法。先调用`init(B builder)`,然后`configure(B builder)` 的俩个方法。先调用`init(B builder)`,然后`configure(B builder)`
后面都是一样,就跳过了 后面都是一样,就跳过了
> applyDefaultConfigurers(http); > applyDefaultConfigurers(http);
这里的这一句,就是从"META-INF/spring.factories" 中加载并实例化给定类型的工厂实现 这里的这一句,就是从 "META-INF/spring.factories" 中加载并实例化给定类型的工厂实现
`SpringFactoriesLoader.loadFactories(AbstractHttpConfigurer.class, classLoader)` `SpringFactoriesLoader.loadFactories(AbstractHttpConfigurer.class, classLoader)`
然后调用`http.apply(configurer);` 添加到`configurers`里面 然后调用`http.apply(configurer);` 添加到`configurers`里面
@ -637,7 +637,7 @@ throw new IllegalArgumentException("The Filter class "+filter.getClass().getName
进行构建这个就是非常重要的一个方法build 对象,老规矩。进入`AbstractConfiguredSecurityBuilder#doBuild()`方法 进行构建这个就是非常重要的一个方法build 对象,老规矩。进入`AbstractConfiguredSecurityBuilder#doBuild()`方法
`beforeInit();`: 还是没有什么 `beforeInit();`: 还是没有什么
`init()`: 调用里面所有的`configurers`里面的`init方法`,后面`HttpSecurity#doBuild`统一讲解,先把流程捋一遍 `init()`: 调用里面所有的`configurers`里面的`init 方法`,后面`HttpSecurity#doBuild`统一讲解,先把流程捋一遍
接下来`SecurityFilterChain`就已经创建好了,看一下里面的方法 接下来`SecurityFilterChain`就已经创建好了,看一下里面的方法
@ -689,22 +689,25 @@ public AuthenticationManagerBuilder authenticationManagerBuilder(ObjectPostProce
} }
``` ```
这里面返回了一个`AuthenticationManagerBuilder`的 bean也就是上面`` 这里面返回了一个`AuthenticationManagerBuilder`的 bean也就是上面`HttpSecurityConfiguration#httpSecurity()`的时候需要的类,这个类也是一个`SecurityBuilder`。
HttpSecurityConfiguration#httpSecurity()`的时候需要的类,这个类也是一个`SecurityBuilder`。
> LazyPasswordEncoder defaultPasswordEncoder = new LazyPasswordEncoder(context); ```java
LazyPasswordEncoder defaultPasswordEncoder = new LazyPasswordEncoder(context);
```
首先创建了一个`LazyPasswordEncoder`,就是`PasswordEncoder`,用来管理密码的 首先创建了一个`LazyPasswordEncoder`,就是`PasswordEncoder`,用来管理密码的
> AuthenticationEventPublisher authenticationEventPublisher = getAuthenticationEventPublisher(context); ```java
AuthenticationEventPublisher authenticationEventPublisher = getAuthenticationEventPublisher(context);
```
这个就是在`SecurityAutoConfiguration`中创建的 springSecurity 的发布订阅,用来订阅事件 这个就是在 `SecurityAutoConfiguration` 中创建的 springSecurity 的发布订阅,用来订阅事件
```java ```java
DefaultPasswordEncoderAuthenticationManagerBuilder result = new DefaultPasswordEncoderAuthenticationManagerBuilder(objectPostProcessor, defaultPasswordEncoder); DefaultPasswordEncoderAuthenticationManagerBuilder result = new DefaultPasswordEncoderAuthenticationManagerBuilder(objectPostProcessor, defaultPasswordEncoder);
``` ```
就是 `AuthenticationManagerBuilder`的真正实现了。接下来回到`getAuthenticationManager()`方法 就是 `AuthenticationManagerBuilder` 的真正实现了。接下来回到`getAuthenticationManager()`方法
```java ```java
public AuthenticationManager getAuthenticationManager() throws Exception { public AuthenticationManager getAuthenticationManager() throws Exception {
@ -1128,7 +1131,7 @@ protected final void updateAuthenticationDefaults() {
2. `this.failureHandler`设置为`new SimpleUrlAuthenticationFailureHandler(authenticationFailureUrl)` 2. `this.failureHandler`设置为`new SimpleUrlAuthenticationFailureHandler(authenticationFailureUrl)`
里面的`authenticationFailureUrl`是`/login + "?error"` 里面的`authenticationFailureUrl`是`/login + "?error"`
`getBuilder().getConfigurer(LogoutConfigurer.class);` 就是前面加入的那一堆`Configurer`中的一个.这个默认就是当前设置的值,不用理会 `getBuilder().getConfigurer(LogoutConfigurer.class);` 就是前面加入的那一堆`Configurer`中的一个 . 这个默认就是当前设置的值,不用理会
> updateAccessDefaults(http); > updateAccessDefaults(http);
@ -1144,8 +1147,8 @@ protected final void updateAuthenticationDefaults() {
```java ```java
/** /**
* 开始一个身份验证方案。 * 开始一个身份验证方案。
在调用该方法之前, ExceptionTranslationFilter将使用请求的目标URL填充HttpSession属性abstractathenticationprocessingfilter.SPRING_SECURITY_SAVED_REQUEST _key。 在调用该方法之前, ExceptionTranslationFilter 将使用请求的目标 URL 填充 HttpSession 属性 abstractathenticationprocessingfilter.SPRING_SECURITY_SAVED_REQUEST _key。
实现应根据需要修改ServletResponse上的标头以开始身份验证过程。 实现应根据需要修改 ServletResponse 上的标头,以开始身份验证过程。
*/ */
private LinkedHashMap<RequestMatcher, AuthenticationEntryPoint> defaultEntryPointMappings=new LinkedHashMap<>(); private LinkedHashMap<RequestMatcher, AuthenticationEntryPoint> defaultEntryPointMappings=new LinkedHashMap<>();

@ -6,7 +6,7 @@
为了方便起见,我们直接在`src/main/resources/resources`目录下创建一个`login.html`(不需要 Controller 跳转): 为了方便起见,我们直接在`src/main/resources/resources`目录下创建一个`login.html`(不需要 Controller 跳转):
``` ```html
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
@ -27,7 +27,7 @@
</html> </html>
``` ```
要怎么做才能让 Spring Security 跳转到我们自己定义的登录页面呢?很简单,只需要在`BrowserSecurityConfig`的`configure`中添加一些配置: 要怎么做才能让 Spring Security 跳转到我们自己定义的登录页面呢?很简单,只需要在 `BrowserSecurityConfig` `configure` 中添加一些配置:
```java ```java
@Configuration @Configuration
@ -58,7 +58,7 @@ public class BrowserConfig extends WebSecurityConfigurerAdapter {
Spring Security 默认会为我们生成一个用户名为 user密码随机的用户实例当然我们也可以定义自己用户信息的获取逻辑只需要实现 Spring Security 提供的**_UserDetailService_**接口即可,该接口只有一个抽象方法**_loadUserByUsername_**,具体实现如下: Spring Security 默认会为我们生成一个用户名为 user密码随机的用户实例当然我们也可以定义自己用户信息的获取逻辑只需要实现 Spring Security 提供的**_UserDetailService_**接口即可,该接口只有一个抽象方法**_loadUserByUsername_**,具体实现如下:
``` ```java
@Service @Service
public class UserDetailService implements UserDetailsService { public class UserDetailService implements UserDetailsService {
@Autowired @Autowired
@ -76,13 +76,13 @@ public class UserDetailService implements UserDetailsService {
### BrowserConfig 配置解析 ### BrowserConfig 配置解析
我们首先来梳理下`BrowserConfig`中的配置是如何被 Spring Security 所加载的。 我们首先来梳理下 `BrowserConfig` 中的配置是如何被 Spring Security 所加载的。
首先找到调用`BrowserConfig`的`configure()`的地方,在其父类`WebSecurityConfigurerAdapter`的`getHttp()`中: 首先找到调用 `BrowserConfig` `configure()` 的地方,在其父类 `WebSecurityConfigurerAdapter` `getHttp()` 中:
![img](https://fastly.jsdelivr.net/gh/doocs/source-code-hunter@main/images/SpringSecurity/12629a18-56ef-4286-9ab9-c124dc3d6791.png) ![img](https://fastly.jsdelivr.net/gh/doocs/source-code-hunter@main/images/SpringSecurity/12629a18-56ef-4286-9ab9-c124dc3d6791.png)
往上一步找到调用`getHttp()`的地方,在同个类的`init()`中: 往上一步找到调用 `getHttp()` 的地方,在同个类的 `init()` 中:
![img](https://fastly.jsdelivr.net/gh/doocs/source-code-hunter@main/images/SpringSecurity/2b54af34-7d68-4f40-8726-d02d18e03dea.png) ![img](https://fastly.jsdelivr.net/gh/doocs/source-code-hunter@main/images/SpringSecurity/2b54af34-7d68-4f40-8726-d02d18e03dea.png)

Loading…
Cancel
Save