如何仅在dev配置文件下于application-dev.yml中禁用CORS?
我正尝试禁用CORS,因为遇到了以下错误:
从源'https://localhost:3000'获取'https://localhost:9000/api/foo'时被CORS策略阻止:预检请求的响应未通过访问控制检查:请求的资源上不存在'Access-Control-Allow-Origin'标头。如果不透明响应符合需求,请将请求的mode设置为'no-cors'以在禁用CORS的情况下获取资源。
Failed to load resource: net::ERR_FAILED
我希望仅当dev配置文件激活时禁用CORS,该如何实现?
我已经尝试了以下配置:
@Configuration @EnableWebMvc public class WebConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedOrigins("*") .allowedMethods("GET", "POST", "PUT", "DELETE", "HEAD") .allowCredentials(true) .maxAge(3600); } }
更新:还有一个我认为与此问题相关的类:
@EnableWebSecurity public class WebSecurityConf extends WebSecurityConfigurerAdapter { @Bean CorsConfigurationSource corsConfigurationSource() { CorsConfiguration config = new CorsConfiguration(); config.setAllowedOrigins(Arrays.asList( "https://example1.com:9000", "https://example2.com:9000" )); config.setAllowCredentials(true); UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/api/**", config); return source; } }
要实现仅在dev环境下宽松配置CORS(等同于禁用跨域限制),核心是利用Spring的Profile条件注解区分环境,同时解决WebMvc和WebSecurity的配置冲突,具体操作如下:
1. 给WebMvc的CORS配置添加dev环境限制
修改WebConfig,加上@Profile("dev")注解,确保只有dev配置激活时才加载这个宽松的CORS规则:
@Configuration @EnableWebMvc @Profile("dev") // 仅dev环境生效 public class WebConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedOrigins("*") .allowedMethods("GET", "POST", "PUT", "DELETE", "HEAD") .allowCredentials(true) .maxAge(3600); } }
2. 修复WebSecurity的CORS配置冲突
你的WebSecurityConf硬编码了固定允许域名,会和dev环境的宽松配置冲突,这里提供两种解决方式:
方式一:分环境定义不同的CORS配置
给不同环境的CORS配置Bean加上Profile注解,dev用宽松规则,生产用严格规则:
@EnableWebSecurity public class WebSecurityConf extends WebSecurityConfigurerAdapter { @Bean @Profile("dev") CorsConfigurationSource devCorsConfigurationSource() { CorsConfiguration config = new CorsConfiguration(); config.setAllowedOrigins(Collections.singletonList("*")); config.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "HEAD")); config.setAllowCredentials(true); UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/**", config); return source; } @Bean @Profile("!dev") CorsConfigurationSource prodCorsConfigurationSource() { CorsConfiguration config = new CorsConfiguration(); config.setAllowedOrigins(Arrays.asList( "https://example1.com:9000", "https://example2.com:9000" )); config.setAllowCredentials(true); UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/api/**", config); return source; } // 必须启用CORS配置 @Override protected void configure(HttpSecurity http) throws Exception { http.cors().and() // 其他安全配置 .authorizeRequests() .anyRequest().authenticated(); } }
方式二:通过配置文件动态读取规则
更灵活的方式是把允许的域名、方法放到配置文件中,dev和生产环境分别配置:
application-dev.properties:cors.allowed-origins=* cors.allowed-methods=GET,POST,PUT,DELETE,HEADapplication-prod.properties:cors.allowed-origins=https://example1.com:9000,https://example2.com:9000 cors.allowed-methods=GET,POST,PUT,DELETE,HEAD- 修改
WebSecurityConf:@EnableWebSecurity @ConfigurationProperties(prefix = "cors") public class WebSecurityConf extends WebSecurityConfigurerAdapter { private List<String> allowedOrigins; private List<String> allowedMethods; // 生成getter和setter @Bean CorsConfigurationSource corsConfigurationSource() { CorsConfiguration config = new CorsConfiguration(); config.setAllowedOrigins(allowedOrigins); config.setAllowedMethods(allowedMethods); config.setAllowCredentials(true); UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/**", config); return source; } @Override protected void configure(HttpSecurity http) throws Exception { http.cors().and() // 其他安全配置 .authorizeRequests() .anyRequest().authenticated(); } }
3. 激活dev配置文件
启动应用时,通过以下方式激活dev profile:
- 命令行参数:
--spring.profiles.active=dev - 全局配置文件:在
application.properties中添加spring.profiles.active=dev
这样就能保证只有dev环境下CORS限制被宽松处理,生产环境保持严格的域名校验。
内容的提问来源于stack exchange,提问作者Trumango

