135 lines
8.0 KiB
Markdown
135 lines
8.0 KiB
Markdown
|
# Spring Security 请求处理流程
|
|||
|
|
|||
|
## 1. 客户端请求
|
|||
|
- 用户发起一个访问请求。
|
|||
|
|
|||
|
## 2. 拦截请求
|
|||
|
- 请求被Spring Security的过滤器链拦截。
|
|||
|
|
|||
|
## 3. 执行认证
|
|||
|
- 通过`AuthenticationManager`对用户进行身份认证。
|
|||
|
|
|||
|
## 4. 认证信息处理
|
|||
|
- 认证成功后,`AuthenticationProvider`会生成一个认证令牌。
|
|||
|
|
|||
|
## 5. 授权决策
|
|||
|
- `AccessDecisionManager`根据用户的权限和访问控制列表(ACLs)来做出授权决策。
|
|||
|
|
|||
|
## 6. 执行授权
|
|||
|
- 通过`ExpressionHandler`来处理表达式,决定是否允许访问特定资源。
|
|||
|
|
|||
|
## 7. 访问资源
|
|||
|
- 如果授权成功,用户可以访问资源。
|
|||
|
|
|||
|
## 8. 处理响应
|
|||
|
- 服务器处理请求并将响应返回给客户端。
|
|||
|
|
|||
|
|
|||
|
# Spring Security 6 中可扩展或自定义的核心接口和类
|
|||
|
|
|||
|
## AuthenticationProvider
|
|||
|
- 当需要实现自定义的用户身份验证逻辑时,可以实现`AuthenticationProvider`接口。
|
|||
|
- 该接口只有一个方法`authenticate(Authentication)`,用于处理传入的认证请求并返回已认证的`Authentication`对象,或者抛出异常表示认证失败。
|
|||
|
|
|||
|
## UserDetailsService
|
|||
|
- 实现`UserDetailsService`接口来提供用户详细信息(如用户名、密码、权限等)的加载逻辑。
|
|||
|
- 这是许多内置`AuthenticationProvider`实现(如`DaoAuthenticationProvider`)的基础,用于从数据源(如数据库、LDAP等)获取用户数据。
|
|||
|
|
|||
|
## PasswordEncoder
|
|||
|
- 虽然Spring Security提供了多种预置的密码编码器,但若需使用自定义的密码哈希算法或与现有系统兼容,可以实现`PasswordEncoder`接口。
|
|||
|
- 该接口定义了密码的编码、验证和升级方法。
|
|||
|
|
|||
|
## AccessDecisionVoter
|
|||
|
- 在授权决策过程中,可以通过实现`AccessDecisionVoter`接口来创建自定义的投票策略。
|
|||
|
- 这些策略可以根据特定条件(如请求属性、用户属性等)对访问请求进行投票,决定是否允许访问。
|
|||
|
|
|||
|
## AuthenticationEntryPoint
|
|||
|
- 当未通过身份验证的用户尝试访问受保护资源时,可以通过实现`AuthenticationEntryPoint`接口来定制如何引导用户进入认证流程,例如重定向到登录页面、返回401 Unauthorized HTTP状态码等。
|
|||
|
|
|||
|
## AuthenticationSuccessHandler / AuthenticationFailureHandler
|
|||
|
- 在表单登录或其他认证过程中,可以自定义成功或失败后的处理逻辑,如跳转页面、返回JSON响应等,这需要实现对应的`AuthenticationSuccessHandler`和`AuthenticationFailureHandler`接口。
|
|||
|
|
|||
|
## LogoutSuccessHandler
|
|||
|
- 实现`LogoutSuccessHandler`接口来指定用户注销成功后的行为,如重定向至特定页面、清除客户端Cookie等。
|
|||
|
|
|||
|
## TokenValidator / OAuth2UserService (针对API安全)
|
|||
|
- 在OAuth2或JWT相关场景下,可能需要实现`TokenValidator`或`OAuth2UserService`等接口来验证和解析令牌,或者提供用户信息。
|
|||
|
|
|||
|
## SecurityFilterChain
|
|||
|
- 虽然不直接扩展接口,但在Spring Security 6 中,创建自定义`SecurityFilterChain` bean是配置安全规则的主要方式。
|
|||
|
- 通过`HttpSecurity` DSL,可以精细地定义过滤器链的行为,如添加自定义过滤器、配置特定路径的访问控制等。
|
|||
|
|
|||
|
## ExceptionTranslator / AuthenticationEntryPoint (针对WebFlux)
|
|||
|
- 在响应式环境中,可能需要自定义异常转换器或认证入口点来处理特定的安全异常和未认证情况。
|
|||
|
|
|||
|
这些接口和类为开发者提供了丰富的扩展点,使他们能够根据实际需求定制Spring Security的行为。在`WebSecurityConfigurerAdapter`的`configure(HttpSecurity http)`方法中的`http`对象来配置具体的HTTP安全规则,如认证方式、授权规则、异常处理等。
|
|||
|
|
|||
|
|
|||
|
# Spring Security 6 工作过程
|
|||
|
|
|||
|
## 1. 启动与配置
|
|||
|
- 在Spring Boot应用启动时,Spring Security通过自动配置或手动配置的方式初始化其组件和安全规则。
|
|||
|
- 配置可能涉及定义认证提供者(如数据库、LDAP、OAuth等)、用户角色映射、访问控制策略、密码编码器、以及定制过滤器链等。
|
|||
|
|
|||
|
## 2. 构建`SecurityFilterChain`
|
|||
|
- Spring Security的核心是构建一个名为`SecurityFilterChain`的过滤器链,它由一系列负责不同安全任务的过滤器组成。
|
|||
|
- 这个过滤链通常通过Java配置类、XML配置或者新的基于WebFlux的DSL方式定义,并按照特定顺序注册到Spring的Web容器中。
|
|||
|
|
|||
|
## 3. 请求处理过程
|
|||
|
- 当客户端发起HTTP请求时,该请求首先会经过`SecurityFilterChain`中的各个过滤器。
|
|||
|
- 过滤器链的工作流程大致如下:
|
|||
|
|
|||
|
### a. `WebAsyncManagerIntegrationFilter`
|
|||
|
- (可选)如果应用支持异步请求,此过滤器确保异步请求的安全上下文正确传播。
|
|||
|
|
|||
|
### b. `SecurityContextPersistenceFilter`
|
|||
|
- 恢复或创建`SecurityContext`(存储认证信息和权限),通常从HTTP会话中加载或新建一个空上下文。
|
|||
|
|
|||
|
### c. `HeaderWriterFilter`
|
|||
|
- 添加必要的安全响应头,如防止跨站脚本攻击(XSS)和点击劫持(CSRF)的防护头。
|
|||
|
|
|||
|
### d. `CorsFilter`
|
|||
|
- (可选)如果启用,处理跨域资源共享(CORS)请求,确保只有符合CORS策略的请求被允许继续。
|
|||
|
|
|||
|
### e. `LogoutFilter`
|
|||
|
- 检查请求是否为注销请求(如 `/logout` URL),如果是,则清除`SecurityContext`并可能执行其他注销逻辑(如清除会话、重定向等)。
|
|||
|
|
|||
|
### f. `OAuth2AuthorizationRequestRedirectFilter` / `OAuth2LoginAuthenticationFilter`
|
|||
|
- (可选)对于OAuth2相关的登录请求,这些过滤器将处理授权码的获取和用户认证流程。
|
|||
|
|
|||
|
### g. `UsernamePasswordAuthenticationFilter`
|
|||
|
- 处理基于表单提交的用户名/密码认证请求,提取凭据并传递给后续的认证管理器进行验证。
|
|||
|
|
|||
|
### h. `RequestCacheAwareFilter`
|
|||
|
- 如果请求需要重新导向到另一个URL以完成认证,此过滤器能缓存原始请求以便认证成功后恢复。
|
|||
|
|
|||
|
### i. `SecurityContextHolderAwareRequestFilter`
|
|||
|
- 将请求包装为`SecurityContextHolderAwareRequestWrapper`,使得安全上下文在整个请求生命周期中可访问。
|
|||
|
|
|||
|
### j. `AnonymousAuthenticationFilter`
|
|||
|
- 如果当前请求尚未经过认证,但应用允许匿名访问,此过滤器将添加一个匿名`Authentication`对象到`SecurityContext`。
|
|||
|
|
|||
|
### k. `SessionManagementFilter`
|
|||
|
- 管理用户会话,如并发会话控制、强制性会话创建等。
|
|||
|
|
|||
|
### l. `ExceptionTranslationFilter`
|
|||
|
- 捕获未授权(`AccessDeniedException`)和其他安全相关异常,将其转换为适当的HTTP响应(如401 Unauthorized、403 Forbidden)或重定向到指定的错误页面。
|
|||
|
|
|||
|
### m. `FilterSecurityInterceptor`
|
|||
|
- 最终的安全决策点,根据配置的访问控制规则(如`@PreAuthorize`注解、`HttpSecurity` DSL定义的路径权限)检查请求是否被授权。如果请求未通过检查,将触发前面提到的异常处理。
|
|||
|
|
|||
|
### n. `SwitchUserFilter`
|
|||
|
- (可选)允许特定用户(如管理员)切换到其他用户的身份来模拟其操作。
|
|||
|
|
|||
|
## 4. 认证与授权
|
|||
|
- 认证过程中,过滤器链中的相关组件会提取请求中的认证信息(如用户名/密码、JWT令牌、OAuth2令牌等),并使用相应的认证提供者进行验证。
|
|||
|
- 验证成功后,一个代表用户身份的`Authentication`对象会被填充并放入`SecurityContext`中。
|
|||
|
- 授权阶段,`FilterSecurityInterceptor`根据已认证用户的角色、权限或其他属性判断其是否有权访问请求的资源。
|
|||
|
|
|||
|
## 5. 响应与清理
|
|||
|
- 如果请求顺利通过所有安全检查,请求将被传递给应用程序的业务逻辑进行处理,并最终返回响应给客户端。
|
|||
|
- 在响应发送给客户端之前,某些过滤器(如`HeaderWriterFilter`)可能还会添加额外的安全响应头。
|
|||
|
- 请求处理完毕后,`SecurityContext`可能被保存回HTTP会话(如果适用)以备后续请求使用。
|
|||
|
|
|||
|
**综上所述**,Spring Security 6 通过构建和执行一个精心设计的过滤器链来对每个进入应用的HTTP请求进行身份验证、授权检查以及必要的异常处理,确保只有经过有效认证且具有足够权限的请求才能访问受保护的资源。
|