Spring Security 6.1.1带认证请求的CORS配置问题排查
Spring Boot 3.1 + Spring Security 6.1.1 CORS 拦截问题排查
将Spring Boot从2.5版本升级至3.1版本(对应Spring Security 6.1.1)后,登录认证的REST接口调用正常,但所有需要认证token的其他REST控制器请求均被CORS策略拦截。已尝试以下操作但均无效:
- 按官方文档配置CORS规则
- 使用
.cors(cors -> cors.disable())禁用CORS - 在REST控制器类上添加
@CrossOrigin注解
确认配置类已添加@Configuration和@EnableWebSecurity注解。
当前CORS配置代码
@Bean CorsConfigurationSource corsConfigurationSource() { CorsConfiguration configuration = new CorsConfiguration(); configuration.addAllowedOriginPattern("*"); configuration.setAllowedMethods(Arrays.asList("GET","POST","PUT","PATCH","DELETE","OPTIONS")); configuration.setAllowCredentials(false); UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/**", configuration); return source; } @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http .cors(cors -> cors.configurationSource(corsConfigurationSource())) //.cors(cors -> cors.disable()) <<--- 按文档配置但无效 .csrf(AbstractHttpConfigurer::disable) .authorizeHttpRequests(request -> request .requestMatchers("/api/auth/**").permitAll() .requestMatchers(SYS_ADMIN_PATTERNS).hasAuthority("SYSTEM_ADMIN") .requestMatchers("/api/v1/**").authenticated() ) .sessionManagement(manager -> manager.sessionCreationPolicy(STATELESS)) .authenticationProvider(authenticationProvider()) .addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class); return http.build(); }
尝试禁用CORS的配置代码
@Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http .cors(cors -> cors.disable()) .csrf(AbstractHttpConfigurer::disable) .authorizeHttpRequests(request -> request .requestMatchers("/api/auth/**").permitAll() .requestMatchers(SYS_ADMIN_PATTERNS).hasAuthority("SYSTEM_ADMIN") .requestMatchers("/api/v1/**").authenticated() ) .sessionManagement(manager -> manager.sessionCreationPolicy(STATELESS)) .authenticationProvider(authenticationProvider()) .addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class); return http.build(); }
问题原因及解决步骤
1. 预检请求(OPTIONS)未被正确放行
Spring Security会拦截OPTIONS请求,当前配置仅放行/api/auth/**的请求,其他接口的OPTIONS预检请求会被认证拦截,导致CORS失败。需明确放行所有OPTIONS请求:
.authorizeHttpRequests(request -> request .requestMatchers(HttpMethod.OPTIONS, "/**").permitAll() // 新增该行 .requestMatchers("/api/auth/**").permitAll() .requestMatchers(SYS_ADMIN_PATTERNS).hasAuthority("SYSTEM_ADMIN") .requestMatchers("/api/v1/**").authenticated() )
2. 确保CORS过滤器优先级
CORS过滤器必须在认证过滤器之前执行。如果自定义了JWT过滤器,可通过注册CorsFilter Bean确保优先级:
@Bean public CorsFilter corsFilter() { return new CorsFilter(corsConfigurationSource()); }
3. 检查AllowCredentials配置
如果前端请求包含凭证(如Cookie),setAllowCredentials(false)会导致CORS失败。若无需凭证可保持设置;若需要,改为true,同时allowedOriginPatterns不能使用*,需指定具体源。
4. 禁用CORS的正确方式
若要完全禁用CORS,需删除全局的corsConfigurationSource() Bean,避免全局配置覆盖Security中的禁用设置,再使用.cors(cors -> cors.disable())配置。
5. @CrossOrigin失效的原因
@CrossOrigin依赖Spring MVC的DispatcherServlet处理,但请求会被Spring Security优先拦截,因此注解配置不会生效,必须通过Spring Security的CORS配置处理。
内容的提问来源于stack exchange,提问作者user1123270
相关产品推荐
相关产品推荐

