2024.11.15 springsecurity执行力逻辑

@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 进行传递。


执行顺序总结:

  1. 请求到达 Spring Security。
  2. JwtAuthorizeFilter 过滤器执行 JWT 校验,如果认证通过,将认证信息保存到 SecurityContextHolder
  3. authorizeHttpRequests 进行授权判断,确认用户是否有权限访问资源。
  4. 如果请求是登录或登出请求,执行相应的处理器(formLoginlogout)。
  5. 如果认证失败,调用 authenticationEntryPoint 进行异常处理。
  6. 如果权限不足,调用 accessDeniedHandler 进行异常处理。

通过这种方式,Spring Security 能够有效地处理身份验证、授权、会话管理等安全问题。

posted @ 2024-11-15 11:18  258333  阅读(14)  评论(0编辑  收藏  举报