迁移到 Spring Boot 2.0.x 时全局 CORS 配置中断
Posted
技术标签:
【中文标题】迁移到 Spring Boot 2.0.x 时全局 CORS 配置中断【英文标题】:Global CORS configuration breaks when migrating to Spring Boot 2.0.x 【发布时间】:2018-10-15 12:23:09 【问题描述】:为什么不再发送我的“Access-Control-Allow-Credentials”以响应 Spring Boot 2.0.x(在我的情况下为 2.0.1.RELEASE)下的预检调用 (OPTIONS)?这是我在 Spring Boot 1.5.6 下运行良好的全局 CORS 配置:
@Configuration
public class CorsConfig
@Bean
public WebMvcConfigurer corsConfigurer()
return new WebMvcConfigurerAdapter()
@Override
public void addCorsMappings(CorsRegistry registry)
registry.addMapping("/**")
.allowedOrigins(
"http://localhost:3000",..)
.allowedMethods("GET", "POST", "PUT", "DELETE", "HEAD");
;
我的 pom 依赖项(我在做自己的安全并避免 Spring Security):
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
我对 REST 端点的服务调用未能通过预检:
无法加载 http://localhost:8080/api/v5/sec/auth:对预检请求的响应未通过访问控制检查:“Access-Control-Allow-Credentials”标头中的值当请求的凭据模式为“包含”时,响应为“”,必须为“真”。因此不允许访问 Origin 'http://localhost:3000'。
我已验证在 Spring Boot 1.5.6 中确实存在“Access-Control-Allow-Credentials”标头,而在 Spring Boot 2.0.1 中则缺失。
我能找到的所有文档,包括 spring.io here 上的最新文档,都表明我的全局配置仍然正确,尽管 WebMvcConfigurerAdapter 现在似乎已被弃用。
更新:
这里是迁移前后的响应头:
迁移前(Spring Boot 1.5.6):
访问控制允许凭据:true 访问控制允许来源:http://localhost:3000 内容类型:application/json;charset=UTF-8 日期:日,日,星期一 yyyy hh:mm:ss GMT 传输编码:分块 变化:起源
迁移后(Spring Boot 2.0.1 - Access-Control-Allow-Credentials 标头缺失,但其他已更改/添加):
访问控制允许标题:内容类型 Access-Control-Allow-Methods: GET,HEAD,POST Access-Control-Allow-Origin: * 访问控制最大年龄:1800 内容长度:0 日期:日,日,星期一 yyyy hh:mm:ss GMT 变化:起源 变化:访问控制请求方法 变化:访问控制请求标头
【问题讨论】:
【参考方案1】:Spring 文档和许多示例都缺少这一点,但答案很简单。我刚刚在 CorsRegistry 上看到了 allowCredentials() 方法,并将 .allowCredentials(true) 添加到注册表方法链中,并重新添加了 Access-Control-Allow-Credentials 标头。
另外,我不再使用已弃用的 WebMvcConfigurerAdapter,而是现在实现 WebMvcConfigurer 并覆盖 addCorsMappings() 方法。
@Configuration
public class CorsConfig implements WebMvcConfigurer
@Override
public void addCorsMappings(CorsRegistry registry)
registry.addMapping("/**")
.allowedOrigins(
"http://localhost:3000",..)
.allowedMethods("GET", "POST", "PUT", "DELETE", "HEAD")
.allowCredentials(true)
;
【讨论】:
就我而言,我将registry.addMapping("/**")
更改为 registry.addMapping("/" )
并且效果很好
这是一个很好的答案,比Spring的官方文档更好。 Spring 文档中提到了使用 WebMvcConfigurerAdapter,这是一个坏主意,因为一旦这样做,您的 IDE 就会警告您它已被弃用。
您好我也面临同样的问题,但上述修复对我不起作用。 @sammoussa.ua 如果还有什么我需要调查的,请告诉我。
您需要定义“没用”。你尝试了什么,它是如何失败的,代码等等。考虑发布一个关于这些项目的新问题。【参考方案2】:
如果您使用的是 Spring Boot 2.0.x
CORS 支持默认禁用,只有在设置 management.endpoints.web.cors.allowed-origins 属性后才会启用。以下配置允许来自 example.com 域的 GET 和 POST 调用:
management.endpoints.web.cors.allowed-origins=http://example.com management.endpoints.web.cors.allowed-methods=GET,POST
欲了解更多信息refer
【讨论】:
这仅适用于 Spring Actuators 暴露的管理端点,不适用于应用程序本身。【参考方案3】:我正在使用 Spring Boot 2.0.2。我有同样的问题,但我使用以下代码来修复它。有人有最好的方法吗?
// Miss `Access-Control-Allow-Origin` header in response using this bean.
// @Bean
// CorsConfigurationSource corsConfigurationSource()
// CorsConfiguration configuration = new CorsConfiguration();
// configuration.setAllowCredentials(true);
// configuration.setAllowedHeaders(Arrays.asList("Authorization", "Cache-Control", "Content-Type"));
// configuration.addAllowedMethod("*");
// configuration.setAllowedOrigins(this.getAllowedOrigins());
// UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
// source.registerCorsConfiguration("/**", configuration);
// return source;
//
@Bean
public FilterRegistrationBean<CorsFilter> initCorsFilter()
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.setAllowedHeaders(Arrays.asList("Authorization", "Cache-Control", "Content-Type"));
config.addAllowedMethod("*");
config.setAllowedOrigins(this.getAllowedOrigins());
source.registerCorsConfiguration("/**", config);
FilterRegistrationBean<CorsFilter> bean = new FilterRegistrationBean<>(new CorsFilter(source));
bean.setOrder(Ordered.HIGHEST_PRECEDENCE);
return bean;
【讨论】:
【参考方案4】:第 1 步:Spring 已经有了 CorsFilter,尽管您可以将自己的 CorsFilter 注册为 bean 以提供您自己的配置。
@Bean
public CorsFilter corsFilter()
final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
final CorsConfiguration config = new CorsConfiguration();
config.setAllowedOrigins(Collections.singletonList("http://localhost:3000")); // Provide list of origins if you want multiple origins
config.setAllowedHeaders(Arrays.asList("Origin", "Content-Type", "Accept"));
config.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "OPTIONS", "DELETE", "PATCH"));
config.setAllowCredentials(true);
source.registerCorsConfiguration("/**", config);
return new CorsFilter(source);
第 2 步:使用@CrossOrigin
注释对控制器进行注释。
【讨论】:
这个对我有用。在没有弄乱我的代码的情况下,我只是添加了这个 bean 并在控制器上添加了 @CrossOrigin 以使其工作。谢谢【参考方案5】:这对我有用(Kotlin):
@Configuration
class CorsConfig : WebMvcConfigurer
override fun addCorsMappings(registry: CorsRegistry)
registry.addMapping("/**")
【讨论】:
以上是关于迁移到 Spring Boot 2.0.x 时全局 CORS 配置中断的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 spring boot 插件 2.0.x 从一个具有不同依赖项的 gradle 项目生成 2 个 jars
迁移到 Spring Boot 2 并使用 Spring Batch 4
从 Spring Boot 1.5.10 迁移到 2.0.0 时无法解析依赖项
迁移到 JDK 11 后 Spring Boot 测试中的 Mockito 错误