日常提交

This commit is contained in:
2022-10-08 23:26:07 +08:00
parent e805a65039
commit 2bf8e02062

View File

@@ -100,3 +100,63 @@ ProviderManager是AuthenticationManager的最通用实现。ProviderManager将
> 在实践中每个AuthenticationProvider知道如何处理一种特定类型的Authentication
默认情况下ProviderManager在认证请求成功后会尝试清除返回的Authentication对象中任何敏感的凭据信息这将会保证password等敏感信息保存时间尽可能地短减少泄露的风险。
### AuthenticationProvider
复数个AuthenticationProvider可以被注入到ProviderManager中每个AuthenticationProvider可以负责一种专门类型的认证例如DaoAuthenticationProvider负责username/password认证JwtAuthenticationProvider负责jwt token的认证。
### AuthenticationEntryPoint
AuthenticationEntryPoint用来发送一个Http Response用来向客户端请求认证凭据。
某些情况下客户端在请求资源时会主动在请求中包含凭据如username/password等。在这种情况下服务端并不需要再专门发送Http Response来向客户端请求认证凭据。
> AuthenticationEntryPoint用来向客户端请求认证凭据AuthenticationEntryPoint的实现可能会执行一个从定向操作将请求重定向到一个登录页面用于获取凭据并且返回一个WWW-Authentication Header。
### AbstractAuthenticationProcessingFilter
该类作为base filter用来对用户的凭据进行认证。再凭据被认证之前Spring Security通常会通过AuthenticationEntryPoint向客户端请求认证凭据。
之后AbstractAuthenticationProcessingFilter会对提交的任何认证请求进行认证。
#### 认证流程
1. 当用户提交认证凭据之后AbstractAuthenticationProcesingFilter会根据HttpServletRequest对象创建一个Authentication对象用于认证该Authentication的类型取决于AbstractAuthenticationProcessingFilter的子类类型。例如UsernamePasswordAuthenticationFilter会通过提交request中的username和password创建UsernamePasswordAuthenticationToken。
2. 然后将构建产生的Authentication对象传入到AuthenticationManager中进行认证
3. 如果认证失败那么会失败SecurityContextHolder会被清空RememberMeService.logFail方法将会被调用AuthenticationFailureHandler也会被调用
4. 如果认证成功那么SessionAuthenticationStrategy将会收到登录的通知
5. 该Authentication对象再认证成功之后将会被设置到SecurityContextHolder中
6. RemeberMeService.logSuccess将会被调用
7. ApplicationEventPublisher发布InteractiveAuthenticationSuccessEvent.
8. AuthenticationSuccessHandler被调用
## 用户名/密码认证
### Form Login
Spring Security为以表单形式提供的用户名和密码认证提供支持。
#### 用户被重定向到登录页面的过程
1. 用户发送了一个没有经过身份认证的请求到指定资源,并且待请求的资源对该用户来说是未授权的
2. Spring Security中FilterSecurityInterceptor抛出AccessDeniedException代表该未授权的请求被拒绝
3. 因为该用户没有经过认证故而ExceptionTransactionFilter发起了开始认证的过程并且使用配置好的AuthenticationEntryPoint向登录页面发起了重定向。在大多数情况下AuthenticationEntryPoint都是LoginUrlAuthenticationEntryPoint
4. 浏览器接下来会请求重定向到的登陆页面
当用户名和密码提交后UsernamePasswordAuthenticationFilter会对username和password进行认证。UsernamePasswordAuthenticationFilter继承了AbstractAuthenticationProcessingFilter。
#### 认证用户名和密码过程
1. 当用户提交了其用户名和密码之后UsernamePasswordAuthenticationFilter会创建一个UsernamePasswordAuthenticationToken
2. 创建的UsernamePasswordAuthenticationToken会传入AuthenticationManager中进行认证
3. 如果认证失败那么SecurityContextHolder会被清除RememberMeService.logFailure和AuthenticationFailureHandler会被调用
4. 如果认证成功那么SessionAuthenticationStrategy将会收到登录的通知RemeberMeService.logSuccess和AuthenticationSuccessHandler会被调用ApplicationEventPublisher发布InteractiveAuthenticationSuccessEvent
Spring Security Form Login默认情况下是开启的但是一旦任何基于servlet的配置被提供那么基于表单的login也必须要显式指定。
```java
// 显式指定form login的配置
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) {
http
.formLogin(withDefaults());
// ...
}
```
如果想要自定义login form page可以使用如下配置
```java
public SecurityFilterChain filterChain(HttpSecurity http) {
http
.formLogin(form -> form
.loginPage("/login")
.permitAll()
);
// ...
}
```