@Configuration
@RequiredArgsConstructor
public class SecurityConfiguration {
private final SecurityHandler securityHandler;
private final JwtAuthorizeFilter jwtAuthorizeFilter;
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
return http
.authorizeHttpRequests(conf -> conf
// 需要校验的接口
.requestMatchers(SecurityConst.AUTH_CHECK_ARRAY).authenticated()
// 注册接口
// 其他的都不用要校验
.anyRequest().permitAll()
)
.formLogin(conf -> conf
// 登录页面
.loginProcessingUrl(SecurityConst.LOGIN_PAGE)
// 成功登录处理
.successHandler(securityHandler::onAuthenticationSuccess)
// 失败登录处理
.failureHandler(securityHandler::onAuthenticationFailure)
)
.logout(conf -> conf
// 登出页面
.logoutUrl(SecurityConst.LOGOUT_PAGE)
// 退出登录处理
.logoutSuccessHandler(securityHandler::onLogoutSuccess)
)
.exceptionHandling(conf -> conf
// 没有登录处理
.authenticationEntryPoint(securityHandler::onUnAuthenticated)
// 没有权限处理
.accessDeniedHandler(securityHandler::onAccessDeny)
)
// 禁用 csrf
.csrf(AbstractHttpConfigurer::disable)
// 不处理 session ,使用token
.sessionManagement(conf -> conf.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
// token 校验添加过滤器
.addFilterBefore(jwtAuthorizeFilter, UsernamePasswordAuthenticationFilter.class)
.build();
}
}
在 Spring Security 中,当请求到达后端时,执行的顺序大致如下:
1. 请求到达 Spring Security
首先,Spring Security 会拦截所有的 HTTP 请求。它会按照你在配置中定义的安全过滤链(SecurityFilterChain
)来依次处理这些请求。
2. SecurityFilterChain
配置生效
SecurityFilterChain
定义了请求的安全策略,它会按照配置的顺序依次执行,配置的顺序对请求的处理结果有影响。在你提供的 SecurityConfiguration
类中,安全过滤链的顺序是:
authorizeHttpRequests
:确定哪些请求需要认证,哪些可以公开访问。formLogin
:如果请求是登录请求,Spring Security 会处理它并触发登录流程。logout
:如果请求是退出登录请求,Spring Security 会处理它并触发注销流程。exceptionHandling
:处理认证失败(未登录或权限不足)时的行为。csrf
:禁用 CSRF 防护(因为你在配置中禁用了 CSRF)。sessionManagement
:指定是否使用 HTTP session,这里是配置为无状态(SessionCreationPolicy.STATELESS
)。addFilterBefore
:添加 JWT 校验过滤器,在执行UsernamePasswordAuthenticationFilter
之前进行。
3. JWT 校验 (JwtAuthorizeFilter
)
当请求到达 Spring Security 后,JwtAuthorizeFilter
会首先被执行,它的职责是解析请求中的 JWT,验证其有效性。如果有效,它会通过 SecurityContextHolder
将认证信息保存到当前请求的上下文中。
- JWT 校验的逻辑:
- 提取请求中的
Authorization
头部(通常是Bearer <token>
)。 - 解析并验证 JWT。如果 JWT 合法,则获取其中的用户信息(如
LoginUser
)。 - 创建
UsernamePasswordAuthenticationToken
对象,这个对象代表认证通过的用户。 - 将认证信息保存到
SecurityContextHolder
中,供后续的授权检查使用。
- 提取请求中的
4. 认证(Authentication)
如果 JwtAuthorizeFilter
过滤器成功认证了请求(即 JWT 验证通过),Spring Security 会使用 SecurityContextHolder
中的 Authentication
对象表示当前认证的用户。
5. 授权(Authorization)
一旦请求通过了身份验证,Spring Security 会继续进行授权处理,即检查用户是否有权限访问请求的资源。
- 通过
authorizeHttpRequests
进行的授权检查会确定当前用户是否有权限访问该请求。如果用户有权限,则继续执行。 - 如果用户没有权限,Spring Security 会触发
accessDeniedHandler
,并返回一个403 Forbidden
错误。
6. 登录和登出
如果请求是登录或登出请求:
- 登录:会调用
formLogin
配置的处理器,在successHandler
中会执行登录成功的逻辑,比如生成 JWT 返回给前端。 - 登出:会调用
logout
配置的处理器,在logoutSuccessHandler
中会执行登出的逻辑。
7. 异常处理
如果请求的用户没有通过认证,Spring Security 会调用 authenticationEntryPoint
来处理未认证的请求,通常是返回一个 401 Unauthorized
错误。如果请求的用户没有足够的权限,则会调用 accessDeniedHandler
,通常是返回一个 403 Forbidden
错误。
8. CSRF 处理
如果你没有禁用 CSRF,那么 Spring Security 会检查每个请求是否带有有效的 CSRF token(防止跨站请求伪造)。但在你的配置中,你显式禁用了 CSRF(csrf(AbstractHttpConfigurer::disable)
),所以这个步骤不会执行。
9. Session 管理
在 sessionManagement
中,你配置了 SessionCreationPolicy.STATELESS
,这意味着 Spring Security 将不会创建或使用 HTTP Session,因此每个请求都是无状态的,认证信息仅通过 JWT 进行传递。
执行顺序总结:
- 请求到达 Spring Security。
JwtAuthorizeFilter
过滤器执行 JWT 校验,如果认证通过,将认证信息保存到SecurityContextHolder
。authorizeHttpRequests
进行授权判断,确认用户是否有权限访问资源。- 如果请求是登录或登出请求,执行相应的处理器(
formLogin
或logout
)。 - 如果认证失败,调用
authenticationEntryPoint
进行异常处理。 - 如果权限不足,调用
accessDeniedHandler
进行异常处理。
通过这种方式,Spring Security 能够有效地处理身份验证、授权、会话管理等安全问题。
标签:2024.11,15,请求,Spring,JWT,springsecurity,conf,Security,认证 From: https://www.cnblogs.com/258-333/p/18547601