Spring Data Rest and Cors

我正在开发一个带有Rest接口和飞镖的Spring Boot应用程序。

XMLHttpRequest确实执行了一个完全正确的选项请求。在此之后,将发出最终的 GET(“/产品”)请求并失败:

请求的资源上不存在“访问控制-允许-源”标头。因此,不允许访问源“http://localhost:63343”。

经过一些调试,我发现以下内容:为除 RepositoryRestHandlerMapping之外的所有子类填充了 AbstractHandlerMapping.corsConfiguration。在 RepositoryRestHandlerMapping 中,在创建时不存在/设置了 corsConfiguration,因此它不会被识别为 cors path/resource。
=> 没有附加 CORS 标头
这可能是问题所在吗?如何设置?

配置类:

@Configuration
public class RestConfiguration extends RepositoryRestMvcConfiguration {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**").allowCredentials(false).allowedOrigins("*").allowedMethods("PUT", "POST", "GET", "OPTIONS", "DELETE").exposedHeaders("Authorization", "Content-Type");
    }

   ...
}

我甚至尝试为每个注释设置Cors:

@CrossOrigin( methods = RequestMethod.GET, allowCredentials = "false")
public interface ProductRepository extends CrudRepository<Product, String> {


}

原始请求标头:

GET /products HTTP/1.1
Host: localhost:8080
Connection: keep-alive
Cache-Control: max-age=0
authorization: Basic dXNlcjpwYXNzd29yZA==
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/43.0.2357.130 Chrome/43.0.2357.130 Safari/537.36
Content-Type: application/json
Accept: */*
Referer: http://localhost:63343/inventory-web/web/index.html
Accept-Encoding: gzip, deflate, sdch
Accept-Language: de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4

原始响应标头:

HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Content-Type: application/hal+json;charset=UTF-8
Transfer-Encoding: chunked
Date: Thu, 30 Jul 2015 15:58:03 GMT

使用的版本: 弹簧靴 1.3.0.M2 弹簧 4.2.0.RC2

我错过了什么?


答案 1

事实上,在Spring Data REST 2.6(Ingalls)之前,只有Spring MVC创建的实例和带有注释的控制器是CORS感知的。HandlerMappingWebMvcConfigurationSupport@CrossOrigin

但是现在DATAREST-573已经修复,现在公开了一个用于全局设置,并且存储库上的注释也被识别,因此这是推荐的方法。有关具体示例,请参阅 https://stackoverflow.com/a/42403956/1092077 答案。RepositoryRestConfigurationgetCorsRegistry()@CrossOrigin

对于那些必须坚持使用Spring Data REST 2.5(Hopper)或以前版本的人来说,我认为最好的解决方案是使用基于过滤器的方法。您显然可以使用Tomcat,Jetty或这个,但请注意,Spring Framework 4.2还提供了一个CorsFilter,它使用相同的CORS处理逻辑和方法。通过将 UrlBasedCorsConfigurationSource 实例传递给构造函数参数,您可以轻松获得像 Spring 本机 CORS 全局支持这样强大的功能。@CrossOriginaddCorsMappings(CorsRegistry registry)CorsFilter

如果您使用的是Spring Boot(支持bean),它可能是这样的:Filter

@Configuration
public class RestConfiguration {

    @Bean
    public FilterRegistrationBean corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration config = new CorsConfiguration().applyPermitDefaultValues();
        source.registerCorsConfiguration("/**", config);
        FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
        bean.setOrder(0);
        return bean;
    }
}

答案 2

由于Ingalls列车已经实现,因此CorS在Spring Data中的支持现在已经启动。有两种方法可以处理:

  1. 指定 、 和 在接口上的注释。@CrossOriginoriginsmethodsallowedHeaders@RepositoryRestResource

    @CrossOrigin(...)
    @RepositoryRestResource
    public interface PageRepository extends CrudRepository<Page, Long> { ... }
    
  2. 具有类内部的全局配置。则无需按 标记存储库。RepositoryRestConfiguration@Configuration@CrossOrigin

    @Configuration
    public class GlobalRepositoryRestConfigurer extends RepositoryRestConfigurerAdapter {
    
        @Override
        public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
            config.getCorsRegistry()
                      .addMapping(CORS_BASE_PATTERN)
                      .allowedOrigins(ALLOWED_ORIGINS)
                      .allowedHeaders(ALLOWED_HEADERS)
                      .allowedMethods(ALLOWED_METHODS);
         }
    
    }