首页 文章

Spring Data Rest和Cors

提问于
浏览
50

我正在开发一个带有Rest接口和dart前端的Spring Boot应用程序 .

XMLHttpRequest确实执行一个完全正确处理的OPTIONS请求 . 在此之后,发出最终的GET(“/ products”)请求并失败:

请求的资源上没有'Access-Control-Allow-Origin'标头 . 因此不允许原点'http://localhost:63343'访问 .

经过一些调试后,我发现了以下内容:为RepositoryRestHandlerMapping之外的所有子类填充了AbstractHandlerMapping.corsConfiguration . 在RepositoryRestHandlerMapping中,没有corsConfiguration在创建时存在/设置,因此它不会被识别为cors路径/资源 .
=>没有附加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

使用的版本:Spring Boot 1.3.0.M2 Spring 4.2.0.RC2

我错过了什么?

4 回答

  • 89

    实际上,在Spring Data REST 2.6(Ingalls)之前,只有由Spring MVC WebMvcConfigurationSupport 创建的 HandlerMapping 实例和用 @CrossOrigin 注释的控制器才能识别CORS .

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

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

    如果您使用的是Spring Boot(支持 Filter beans),它可能类似于:

    @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;
        }
    }
    
  • 7

    the Ingalls train has been realised以来,现在开始在Spring Data中支持CORS . 有两种方法可以解决:

    • @CrossOrigin 注释,通过 @RepositoryRestResource 接口指定 originsmethodsallowedHeaders .
    @CrossOrigin(...)
    @RepositoryRestResource
    public interface PageRepository extends CrudRepository<Page, Long> { ... }
    
    • @Configuration 类中 RepositoryRestConfiguration 的全局配置 . 然后不需要 @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);
         }
    
    }
    
  • 0

    出于某种原因,从Spring Boot 1.5.2升级到1.5.6后,上面接受的答案中建议的方法对我不起作用 .

    正如@BigDong的评论所指出的那样,我得到的例外是:

    BeanInstantiationException:无法实例化[javax.servlet.Filter]:工厂方法'springSecurityFilterChain'抛出异常;嵌套异常是org.springframework.beans.factory.BeanNotOfRequiredTypeException:名为'corsFilter'的bean应该是'org.springframework.web.filter.CorsFilter'类型,但实际上是'org.springframework.boot.web.servlet'类型.FilterRegistrationBean

    所以我在这里得到的是为REST API中的所有 endpoints 获取“全局”CORS配置,无论它们是使用Spring Data Rest还是Spring MVC实现的,所有 endpoints 都受Spring Security保护 .

    我无法在正确的位置将 CorsFilter 挂钩到请求管道中,所以我分别配置了SDR和MVC,但是通过这个帮助器为它们的 CorsRegistry 使用了相同的配置:

    public static void applyFullCorsAllowedPolicy(CorsRegistry registry) {
        registry.addMapping("/**") //
                .allowedOrigins("*") //
                .allowedMethods("OPTIONS", "HEAD", "GET", "PUT", "POST", "DELETE", "PATCH") //
                .allowedHeaders("*") //
                .exposedHeaders("WWW-Authenticate") //
                .allowCredentials(true)
                .maxAge(TimeUnit.DAYS.toSeconds(1));
    }
    

    然后对于MVC:

    @Configuration
    @EnableWebSecurity(debug = true)
    @EnableGlobalMethodSecurity(prePostEnabled = true)
    public class CustomWebSecurityConfiguration extends WebSecurityConfigurerAdapter {
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            // enables CORS as per
            // https://docs.spring.io/spring-security/site/docs/current/reference/html/cors.html#cors
            http.cors()
                .and() // ...
        }
    
        @Bean
        public WebMvcConfigurer corsConfigurer() {
            return new WebMvcConfigurerAdapter() {
                @Override
                public void addCorsMappings(CorsRegistry registry) {
                    applyFullCorsAllowedPolicy(registry);
                }
            };
        }
    }
    

    然后是SDR:

    public class CustomRepositoryRestMvcConfiguration extends RepositoryRestConfigurerAdapter {
    
    @Override
    public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
        config.setReturnBodyOnCreate(true);
        config.setReturnBodyForPutAndPost(true);
        config.setReturnBodyOnUpdate(true);
        config.setMaxPageSize(250);
        config.setDefaultPageSize(50);
        config.setDefaultMediaType(MediaTypes.HAL_JSON);
        config.useHalAsDefaultJsonMediaType(true);
    
        CustomWebSecurityConfiguration.applyFullCorsAllowedPolicy(config.getCorsRegistry());
    }
    

    这里有一些关于这个主题的进一步参考,帮助我得出了这个答案:

  • 15

    我正试图从角度来打 spring 休息服务 . 部署在tomcat服务器中的Spring rest项目和angular是默认的角度服务器 . 从角度到服务,我遇到了这个问题 . 我试着跟着

    https://juristr.com/blog/2016/11/configure-proxy-api-angular-cli/

    但问题仍然存在 . 感谢我的高级'Abbas bhai',他建议请在spring配置文件中添加一些配置以避免这个问题,所以我在spring配置中添加了这段代码 .

    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.servlet.config.annotation.CorsRegistry;
    import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
    import org.springframework.web.servlet.config.annotation.EnableWebMvc;
    import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
    
    @Configuration
    @EnableWebMvc
    @ComponentScan("org.liferayasif.backend")
    public class RestConfig extends WebMvcConfigurerAdapter{
    
        @Override
        public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer){
            configurer.enable();
        }
    
        /*
         * (non-Javadoc)
         * @see org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter#addCorsMappings(org.springframework.web.servlet.config.annotation.CorsRegistry)
         * To avoid 'Access-Control-Allow-Origin'
         * Above error arising when I am hitting from angular to our rest service
         */
        @Override
        public void addCorsMappings(CorsRegistry registry) {
            registry.addMapping("/**");
        }
    
    }
    

    这个方法解决了我的'Access-Control-Allow-Origin'角色 .

    @Override
        public void addCorsMappings(CorsRegistry registry) {
            registry.addMapping("/**");
        }
    

    供参考可以下载我的整个项目

    我的github网址链接:

    https://github.com/asifaftab87/SpringPersistenceHibernate

    分支 - 安全

    项目 - 模型

相关问题