在 Spring Boot 3.4.x 中,HttpSecurity 的 and() 方法已经被标记为过时,因此我们需要采用新的 Lambda 风格 API 来配置安全性。你可以将 exceptionHandling() 移到 HttpSecurity 的顶层配置中,而不是在 authorizeHttpRequests 的内部。
authenticationEntryPoint和accessDeniedHandler的自定义
- import jakarta.servlet.http.HttpServletRequest;
- import jakarta.servlet.http.HttpServletResponse;
- import org.springframework.security.access.AccessDeniedException;
- import org.springframework.security.web.access.AccessDeniedHandler;
- import java.io.IOException;
- public class CustomAccessDeineHandler implements AccessDeniedHandler {
- @Override
- public void handle(HttpServletRequest request,
- HttpServletResponse response,
- AccessDeniedException accessDeniedException) throws IOException {
- response.setContentType("application/json");
- response.setStatus(HttpServletResponse.SC_FORBIDDEN);
- response.getWriter().write("{"error": "forbidden", "message": "" + accessDeniedException.getMessage() + ""}");
- }
- }
- import jakarta.servlet.http.HttpServletRequest;
- import jakarta.servlet.http.HttpServletResponse;
- import org.springframework.security.core.AuthenticationException;
- import org.springframework.security.web.AuthenticationEntryPoint;
- import java.io.IOException;
- /**
- * 默认的认证入口点,当用户未通过认证时会触发此类,返回401状态码和错误信息。
- * @author lind
- * @date 2025/5/28 16:59
- * @since 1.0.0
- */
- public class CustomAuthenticationEntryPoint implements AuthenticationEntryPoint {
- @Override
- public void commence(HttpServletRequest request,
- HttpServletResponse response,
- AuthenticationException authException) throws IOException {
- response.setContentType("application/json");
- response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
- response.getWriter().write("{"error": "Unauthorized", "message": "" + authException.getMessage() + ""}");
- }
- }
复制代码 HandlerConfig注册bean
- @Configuration
- public class HandlerConfig {
- @Bean
- @ConditionalOnMissingBean
- AuthenticationEntryPoint authenticationEntryPoint() {
- return new CustomAuthenticationEntryPoint();
- }
- @Bean
- @ConditionalOnMissingBean
- public AccessDeniedHandler accessDeniedHandler() {
- return new CustomAccessDeineHandler();
- }
- }
复制代码 WebSecurityConfig代码
- @EnableWebSecurity
- public class WebSecurityConfig {
- private UaaProperty uaaProperty;
- private AuthenticationEntryPoint authenticationEntryPoint;
- private AccessDeniedHandler accessDeniedHandler;
- public WebSecurityConfig(UaaProperty uaaProperty, AuthenticationEntryPoint authenticationEntryPoint, AccessDeniedHandler accessDeniedHandler) {
- this.uaaProperty = uaaProperty;
- this.authenticationEntryPoint = authenticationEntryPoint;
- this.accessDeniedHandler = accessDeniedHandler;
- }
- @Bean
- public JwtAuthenticationFilter jwtAuthenticationFilter() {
- return new JwtAuthenticationFilter(uaaProperty);
- }
- @Bean
- public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
- Set<String> set = new HashSet<>();
- if (uaaProperty.getPermitUrl() != null && uaaProperty.getPermitUrl().length > 0) {
- Collections.addAll(set, uaaProperty.getPermitUrl());
- }
- http.csrf(csrf -> csrf.disable())
- .authorizeHttpRequests(authorize -> authorize
- .requestMatchers(set.toArray(new String[]{})).permitAll()
- .anyRequest().authenticated()
- )
- .exceptionHandling(exceptionHandling ->
- exceptionHandling
- .authenticationEntryPoint(authenticationEntryPoint)
- .accessDeniedHandler(accessDeniedHandler)
- )
- .addFilterBefore(jwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
- return http.build();
- }
- }
复制代码 JwtAuthenticationFilter实现自定义验证逻辑
- public class JwtAuthenticationFilter extends OncePerRequestFilter {
- // 配置白名单策略,不走当前doFilterInternal
- @Override
- protected boolean shouldNotFilter(HttpServletRequest request) {
-
- }
- @Override
- protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
- throws ServletException, IOException {
-
- }
- }
复制代码 新版3.x的SPI风格自动装配
- resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
- com.xxx.uaa.keycloak.config.UaaProperty
- com.xxx.uaa.keycloak.config.WebSecurityConfig
- com.xxx.uaa.keycloak.config.HandlerConfig
复制代码 关键点解释
- Lambda 风格 API:使用 exceptionHandling(exceptionHandling -> ...) 的方式来设置 authenticationEntryPoint 和 accessDeniedHandler,这符合新的配置风格,避免了使用过时的方法。
- 结构清晰:通过这种方法,你的代码结构更加清晰,逻辑分离也更明显。
- 保持原有逻辑:其余部分的逻辑保持不变,仍然可以根据需要添加其他的配置。
注意事项
- 确保你的 Spring Security 版本已经更新到 5.4 或更高版本,以支持这种新的配置方式。
- 如果你有其他的异常处理或安全配置,也可以在同一链中继续添加。
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |