找回密码
 立即注册
首页 业界区 安全 springboot~3.x版本的认证逻辑

springboot~3.x版本的认证逻辑

懵诬哇 2025-5-30 14:35:22
在 Spring Boot 3.4.x 中,HttpSecurity 的 and() 方法已经被标记为过时,因此我们需要采用新的 Lambda 风格 API 来配置安全性。你可以将 exceptionHandling() 移到 HttpSecurity 的顶层配置中,而不是在 authorizeHttpRequests 的内部。
authenticationEntryPoint和accessDeniedHandler的自定义
  1. import jakarta.servlet.http.HttpServletRequest;
  2. import jakarta.servlet.http.HttpServletResponse;
  3. import org.springframework.security.access.AccessDeniedException;
  4. import org.springframework.security.web.access.AccessDeniedHandler;
  5. import java.io.IOException;
  6. public class CustomAccessDeineHandler implements AccessDeniedHandler {
  7.     @Override
  8.     public void handle(HttpServletRequest request,
  9.                        HttpServletResponse response,
  10.                        AccessDeniedException accessDeniedException) throws IOException {
  11.         response.setContentType("application/json");
  12.         response.setStatus(HttpServletResponse.SC_FORBIDDEN);
  13.         response.getWriter().write("{"error": "forbidden", "message": "" + accessDeniedException.getMessage() + ""}");
  14.     }
  15. }
  16. import jakarta.servlet.http.HttpServletRequest;
  17. import jakarta.servlet.http.HttpServletResponse;
  18. import org.springframework.security.core.AuthenticationException;
  19. import org.springframework.security.web.AuthenticationEntryPoint;
  20. import java.io.IOException;
  21. /**
  22. * 默认的认证入口点,当用户未通过认证时会触发此类,返回401状态码和错误信息。
  23. * @author lind
  24. * @date 2025/5/28 16:59
  25. * @since 1.0.0
  26. */
  27. public class CustomAuthenticationEntryPoint implements AuthenticationEntryPoint {
  28.     @Override
  29.     public void commence(HttpServletRequest request,
  30.                          HttpServletResponse response,
  31.                          AuthenticationException authException) throws IOException {
  32.         response.setContentType("application/json");
  33.         response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
  34.         response.getWriter().write("{"error": "Unauthorized", "message": "" + authException.getMessage() + ""}");
  35.     }
  36. }
复制代码
HandlerConfig注册bean
  1. @Configuration
  2. public class HandlerConfig {
  3.     @Bean
  4.     @ConditionalOnMissingBean
  5.     AuthenticationEntryPoint authenticationEntryPoint() {
  6.         return new CustomAuthenticationEntryPoint();
  7.     }
  8.     @Bean
  9.     @ConditionalOnMissingBean
  10.     public AccessDeniedHandler accessDeniedHandler() {
  11.         return new CustomAccessDeineHandler();
  12.     }
  13. }
复制代码
WebSecurityConfig代码
  1. @EnableWebSecurity
  2. public class WebSecurityConfig {
  3.     private UaaProperty uaaProperty;
  4.     private AuthenticationEntryPoint authenticationEntryPoint;
  5.     private AccessDeniedHandler accessDeniedHandler;
  6.     public WebSecurityConfig(UaaProperty uaaProperty, AuthenticationEntryPoint authenticationEntryPoint, AccessDeniedHandler accessDeniedHandler) {
  7.         this.uaaProperty = uaaProperty;
  8.         this.authenticationEntryPoint = authenticationEntryPoint;
  9.         this.accessDeniedHandler = accessDeniedHandler;
  10.     }
  11.     @Bean
  12.     public JwtAuthenticationFilter jwtAuthenticationFilter() {
  13.         return new JwtAuthenticationFilter(uaaProperty);
  14.     }
  15.     @Bean
  16.     public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
  17.         Set<String> set = new HashSet<>();
  18.         if (uaaProperty.getPermitUrl() != null && uaaProperty.getPermitUrl().length > 0) {
  19.             Collections.addAll(set, uaaProperty.getPermitUrl());
  20.         }
  21.         http.csrf(csrf -> csrf.disable())
  22.                 .authorizeHttpRequests(authorize -> authorize
  23.                         .requestMatchers(set.toArray(new String[]{})).permitAll()
  24.                         .anyRequest().authenticated()
  25.                 )
  26.                 .exceptionHandling(exceptionHandling ->
  27.                         exceptionHandling
  28.                                 .authenticationEntryPoint(authenticationEntryPoint)
  29.                                 .accessDeniedHandler(accessDeniedHandler)
  30.                 )
  31.                 .addFilterBefore(jwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
  32.         return http.build();
  33.     }
  34. }
复制代码
JwtAuthenticationFilter实现自定义验证逻辑
  1. public class JwtAuthenticationFilter extends OncePerRequestFilter {
  2.     // 配置白名单策略,不走当前doFilterInternal
  3.     @Override
  4.     protected boolean shouldNotFilter(HttpServletRequest request) {
  5.         
  6.     }
  7.     @Override
  8.     protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
  9.             throws ServletException, IOException {
  10.                
  11.     }
  12. }
复制代码
新版3.x的SPI风格自动装配


  • resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
  1. com.xxx.uaa.keycloak.config.UaaProperty
  2. com.xxx.uaa.keycloak.config.WebSecurityConfig
  3. com.xxx.uaa.keycloak.config.HandlerConfig
复制代码
关键点解释


  • Lambda 风格 API:使用 exceptionHandling(exceptionHandling -> ...) 的方式来设置 authenticationEntryPoint 和 accessDeniedHandler,这符合新的配置风格,避免了使用过时的方法。
  • 结构清晰:通过这种方法,你的代码结构更加清晰,逻辑分离也更明显。
  • 保持原有逻辑:其余部分的逻辑保持不变,仍然可以根据需要添加其他的配置。
注意事项


  • 确保你的 Spring Security 版本已经更新到 5.4 或更高版本,以支持这种新的配置方式。
  • 如果你有其他的异常处理或安全配置,也可以在同一链中继续添加。

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册