无法在 Spring Boot Data Rest 中启用 CORS

Posted

技术标签:

【中文标题】无法在 Spring Boot Data Rest 中启用 CORS【英文标题】:cant enable CORS in spring boot data rest 【发布时间】:2016-12-04 12:09:54 【问题描述】:

我需要在我的 spring boot data rest api 中启用全局 CORS,以防止每当我从浏览器调用我的 api 时出现以下错误: http://localhost:8090/posts?user-id=1。请求的资源上不存在“Access-Control-Allow-Origin”标头。因此,Origin 'http://localhost' 不允许访问。'。

我可以在浏览器中输入 url 并接收到该资源的正确获取响应,但我无法通过网页中的 ajax 调用进行相同的调用。

任何想法我缺少什么?

我的代码和配置如下:

@SpringBootApplication
@EnableAutoConfiguration
@EnableJpaRepositories
@EnableWebMvc
public class Application  

public static void main(String[] args) 
    SpringApplication.run(Application.class, args);



@Bean
public WebMvcConfigurer corsConfigurer() 

    return new WebMvcConfigurerAdapter() 
        @Override
        public void addCorsMappings(CorsRegistry registry) 
            registry.addMapping("/**");
        
    ;


@Bean
public CommandLineRunner demo(UserRepository userRepository, PostRepository postRepository,
                              CommentRepository commentRepository, EventRepository eventRepository, VenueRepository venueRepository) 
    return (args) -> 

        User user = new User("fsdsdfsd","sdsdsds","121212");
        userRepository.save(user);

        Venue venue = new Venue("dsaesrdfddgd","aerttyhyyty","yyyyyyyyyyyyyy");
        venueRepository.save(venue);

        Event event = new Event("dsaesrdfddgd","aerttyhyyty","yyyyyyyyyyyyyy",venue,user);
        eventRepository.save(event);

        Post post = new Post("some posts are funny. Some are not.",user, event);
        postRepository.save(post);

        Comment comment = new Comment("commmentntnrnejfnerfdgdfgdfdt", user, post);
        commentRepository.save(comment);
    ;

@RepositoryRestResource
public interface PostRepository extends PagingAndSortingRepository<Post, Long> 


Page<Post> readBydeletedIsFalseOrderByCreated(Pageable pageRequest);

@CrossOrigin
Post readByIdAndDeletedIsFalse(Long postId);

buildscript 
repositories 
    mavenCentral()

dependencies 
    classpath("org.springframework.boot:spring-boot-gradle-plugin:1.3.6.RELEASE")



apply plugin: 'java'
apply plugin: 'war'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'spring-boot'

jar 
    baseName = 'project'
    version = '0.1.0'


war 
    baseName = 'project'
    version = '0.1.0'



repositories 
    mavenCentral()


sourceCompatibility = 1.8
targetCompatibility = 1.8

dependencies 
    compile("org.springframework.boot:spring-boot-starter-data-rest")
    compile("org.springframework.boot:spring-boot-starter-data-jpa")
    compile("com.h2database:h2")


task wrapper(type: Wrapper) 
    gradleVersion = '2.3'

【问题讨论】:

您好,请检查这个项目github.com/MFaisalHyder/REST_API 它完全是使用带有 Spring Boot 的 Spring MVC4 制作的。在您的帖子中,您缺少为响应标头设置过滤器,并且还必须允许从应用程序使用 GET、POST 等原始方法。如果不理解,请通过项目,我将在完整的答案中描述。 非常感谢。我试试这个 您收到了吗,或者您希望我发布详细的答案,但您也需要发布您的项目结构,因为它需要更改。 嗯,老实说,我很挣扎,虽然这篇文章看起来真的是我想要的。如果您能帮助我提供更详细的答案,我将不胜感激。至于项目结构....我目前将所有内容都保存在一个名为 hello 的包中——这不是一件好事,但我的项目已经被缩减了,所以我可以先让简单的事情开始工作——所以现在还可以 问题是,如果你在 GOD 课程中工作,事情就不会是模块化的。 spring.io/guides/gs/rest-service 按照他们的指南设置您的项目。! 【参考方案1】:

尝试将其添加到全局配置中:

registry.addMapping("/**").allowedOrigins("*");

【讨论】:

这看起来很有希望,所以我在我的 WebMvcConfigurer bean 声明中修改了这一行。不幸的是,这并没有什么不同。 很奇怪,它可以完美地用于常规休息端点。我认为您不需要带有全局配置的 @crossorigin 注释 可能是对其余存储库的限制,请尝试使用 cors 过滤器。 Tomcat 自带一个 或者实现您自己的非常基本的一个,将访问控制标头填充到 *【参考方案2】:

所以在 cmets 中讨论了我的发现后,您可以在您的 addCorsMappings 方法中尝试此操作

registry.addMapping("/**").allowedOrigins("http://localhost:8090")
                          .allowedMethods("PUT", "DELETE", "GET", "POST");

【讨论】:

不幸的是,这没有帮助,但感谢您的建议。我很难相信 Pivotal Spring 的人们会费心去创建 spring-data-rest 如果它不能用于跨源请求。一定有办法做到这一点 spring.io/blog/2015/06/08/cors-support-in-spring-framework 这会帮助你 谢谢。有一个部分看起来很有希望 - 当然它是关于当前不支持本机 cors 的 Spring Boot 项目的基于过滤器的替代方法(例如...data-rest lol)!我必须跑腿,但当我回来的时候我会试试这个。生病让你知道它是怎么回事。谢谢! 是的!!!太感谢了。这基本上是通过使用基于过滤器的方法来实现的。在本小节“基于过滤器的 CORS 支持”中,我尝试了几种几乎相同的方法,但这里的细微差别解决了它!今日英雄!! :)【参考方案3】:

添加这个 bean 会有所帮助

@Bean
public FilterRegistrationBean corsFilter() 
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    CorsConfiguration config = new CorsConfiguration();
    config.setAllowCredentials(true);
    config.addAllowedOrigin("*");
    config.addAllowedHeader("*");
    config.addAllowedMethod("GET");
    source.registerCorsConfiguration("/**", config);
    FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
    bean.setOrder(0);
    return bean;

有趣的是,spring 不允许使用以下 bean 对 spring 引导数据休息端点提供 CORS 支持。但是,它可以与开发人员创建的其他自定义端点一起正常工作。

@Bean
public WebMvcConfigurer corsConfigurer() 

    return new WebMvcConfigurerAdapter() 
        @Override
        public void addCorsMappings(CorsRegistry registry) 
            registry.addMapping("/**").allowedOrigins("*").allowedMethods("GET");
        
    ;

【讨论】:

以上是关于无法在 Spring Boot Data Rest 中启用 CORS的主要内容,如果未能解决你的问题,请参考以下文章

Spring boot:无法从另一个 Origin 访问安全资源 - CORS - Spring Security - Spring data rest

Spring Boot Data Rest + CORS 未正确启用 OPTIONS/DELETE

Spring boot 2.0.3.RELEASE, Spring data rest, application error, failed to start

初入spring boot(八 )Spring Data REST

在Spring Boot Data JPA Rest API中使用PostgreSql时,表未找到错误

您如何保护 Spring Boot / Spring-Data Rest 以便用户只能访问他自己的实体