Spring Boot配置CORS allowCredentials为true时报*值错误的解决方法
错误根因
Spring Boot 2.4.0+版本强制遵循浏览器CORS安全规则:当配置项allowCredentials = true(允许跨域请求携带Cookie、认证头、TLS证书等凭证)时,allowedOrigins不能设置为通配符*——该值会直接写入Access-Control-Allow-Origin响应头,而携带凭证的跨域请求不允许该头为通配符,否则就会抛出题目中给出的IllegalArgumentException。
解决方案
方案1:修正WebSecurityConfig类配置(适配现有代码,生产环境推荐)
直接替换你现有CORS配置逻辑即可,原有Spring Security的权限拦截、CSRF等配置保持不变:
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.web.SecurityFilterChain; 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 WebSecurityConfig { @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http // 挂载自定义CORS配置源 .cors(cors -> cors.configurationSource(corsConfigurationSource())) // 下方保留你原有的csrf配置、接口拦截规则、登录逻辑等即可 .csrf().disable() .authorizeHttpRequests(auth -> auth.anyRequest().authenticated()); return http.build(); } @Bean CorsConfigurationSource corsConfigurationSource() { CorsConfiguration config = new CorsConfiguration(); // 二选一:生产环境优先用显式源配置,安全性更高,值必须和前端访问地址完全一致(带协议、端口,无末尾斜杠) config.setAllowedOrigins(List.of("http://localhost:3000")); // 二选一:本地开发多端口调试、多源场景可以用模式匹配,不要和上面的allowedOrigins同时配置 // config.setAllowedOriginPatterns(List.of("http://localhost:*")); config.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE", "OPTIONS", "PATCH")); config.setAllowedHeaders(List.of("*")); // 允许跨域携带凭证 config.setAllowCredentials(true); // 预检请求缓存时间,单位秒,减少OPTIONS请求次数 config.setMaxAge(3600L); UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); // 对所有接口路径生效 source.registerCorsConfiguration("/**", config); return source; } }
前端配套配置:如果开启
allowCredentials = true,React侧使用axios发请求需要加全局配置axios.defaults.withCredentials = true;使用原生fetch需要在请求参数中设置credentials: 'include',否则请求不会携带凭证信息。
方案2:通过application.yml全局配置(无需编写Java配置类)
如果不需要在Security配置中做定制化CORS逻辑,可以直接用配置文件实现:
spring: web: cors: # 二选一:显式指定允许源 allowed-origins: "http://localhost:3000" # 二选一:模式匹配 # allowed-origin-patterns: "http://localhost:*" allowed-methods: "GET,POST,PUT,DELETE,OPTIONS,PATCH" allowed-headers: "*" allow-credentials: true max-age: 3600 # 对所有接口路径生效 mapping-path: "/**"
方案3:通过application.properties全局配置
# 二选一:显式指定允许源 spring.web.cors.allowed-origins=http://localhost:3000 # 二选一:模式匹配 # spring.web.cors.allowed-origin-patterns=http://localhost:* spring.web.cors.allowed-methods=GET,POST,PUT,DELETE,OPTIONS,PATCH spring.web.cors.allowed-headers=* spring.web.cors.allow-credentials=true spring.web.cors.max-age=3600 spring.web.cors.mapping-path=/**
注意:如果同时存在Java配置类的CORS规则和配置文件的CORS规则,Java配置优先级更高,会覆盖配置文件的逻辑,不要重复配置避免规则不生效。配置修改后需要重启后端服务。
内容的提问来源于stack exchange,提问作者Đỗ Như Vỹ
相关产品推荐
相关产品推荐

