Spring Security配置部分端点免认证时遭遇403错误求助
Spring Boot 3.2.0 Spring Security 权限配置问题解决指南
一、核心问题排查
1. 路径匹配错误
你配置的api/login、api/register缺少开头的斜杠/,Spring Security的路径匹配严格基于完整路径,无斜杠会导致匿名访问规则不匹配,请求被后续认证规则拦截返回403。必须写成/api/login、/api/register。
2. 规则顺序问题
Spring Security的权限规则从上到下依次匹配,匹配到第一条规则后停止处理。必须把匿名访问规则放在需要认证的规则之前,否则会先触发认证拦截。
二、正确配置示例
以下是适配Spring Boot 3.2.0的完整配置,解决端点权限、无状态会话、CORS弃用等问题:
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.authentication.AuthenticationProvider; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.cors.CorsConfigurationSource; import org.springframework.web.cors.UrlBasedCorsConfigurationSource; import java.util.List; @Configuration @EnableWebSecurity public class SecurityConfig { private final AuthenticationProvider customAuthenticationProvider; private final YourCustomFilter customFilter; // 你的自定义过滤器 public SecurityConfig(AuthenticationProvider customAuthenticationProvider, YourCustomFilter customFilter) { this.customAuthenticationProvider = customAuthenticationProvider; this.customFilter = customFilter; } @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http // 无状态应用禁用CSRF .csrf(csrf -> csrf.disable()) // 配置CORS(替代弃用的http.cors()) .cors(cors -> cors.configurationSource(corsConfigurationSource())) // 开启无状态会话 .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) // 权限规则:先放匿名访问,再放需认证路径 .authorizeHttpRequests(auth -> auth .requestMatchers("/api/login", "/api/register", "/api/**").permitAll() .requestMatchers("/api/auth/**").authenticated() .anyRequest().authenticated() ) // 注册自定义认证提供者 .authenticationProvider(customAuthenticationProvider) // 插入自定义过滤器到指定位置 .addFilterBefore(customFilter, UsernamePasswordAuthenticationFilter.class); return http.build(); } // CORS配置Bean,替代弃用的http.cors() @Bean public CorsConfigurationSource corsConfigurationSource() { CorsConfiguration config = new CorsConfiguration(); // 根据业务需求配置允许的源、方法、头 config.setAllowedOrigins(List.of("http://localhost:3000")); config.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE", "OPTIONS")); config.setAllowedHeaders(List.of("*")); config.setAllowCredentials(true); UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/**", config); return source; } }
三、其他可能导致403的原因
- 自定义过滤器顺序/逻辑错误:如果自定义过滤器拦截了匿名请求,或逻辑中错误拒绝未认证请求,会导致403。确保过滤器只处理需认证路径,或放过匿名请求。
- 认证提供者逻辑问题:检查自定义
AuthenticationProvider的authenticate方法,是否错误对匿名请求做了认证校验,导致返回认证失败。 - 请求方法拦截:若
login是POST请求,未禁用CSRF时会被默认拦截,无状态场景必须禁用CSRF。
内容的提问来源于stack exchange,提问作者Saurav
相关产品推荐
相关产品推荐

