没有为OPTIONS / DELETE正确启用Spring Boot Data Rest + CORS [英] Spring Boot Data Rest + CORS not being enabled properly for OPTIONS/DELETE

查看:136
本文介绍了没有为OPTIONS / DELETE正确启用Spring Boot Data Rest + CORS的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个非常简单的例子,我无法开始工作。

I've got an extremely simple example that I can't get to work.

我的域名为我的数据库和我的存储库建模。

I have my domain that models my database, and my Repository.

public interface MyTestRepository extends CrudRepository<MyTest, Integer> {
}

我用 http://resttesttest.com/ 来测试它。对于GET方法,它返回JSON REST信息没有任何问题。

I used http://resttesttest.com/ to test it. For GET Method's it returns me the JSON REST information without any issue.

我可以查询端点 http:// localhost:8080 / mytest / 1 我从数据库中获取id = 1的信息。

I can query the endpoint http://localhost:8080/mytest/1 and I get back the information for id=1 from the database.

但是,当我尝试使用DELETE选项时会出现问题。如果我在 http:// localhost:8080 / mytest / 1 上运行DELETE,我会得到

However, the problem comes in when I try to use the DELETE option. If I run a DELETE on http://localhost:8080/mytest/1 I get


对预检请求的响应未通过访问控制检查:否
'Access-Control-Allow-Origin'标头出现在请求
资源。因此,不允许
访问来源' http://resttesttest.com '。响应的HTTP状态代码为403.

Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://resttesttest.com' is therefore not allowed access. The response had HTTP status code 403.

我最初尝试了以下内容,但发现我无法使用它,因为我'使用Spring-data-Rest。 https://jira.spring.io/browse/DATAREST-573

I initially tried the following, but found out that I can't use it because I'm using Spring-data-Rest. https://jira.spring.io/browse/DATAREST-573

@Override
public void addCorsMappings(CorsRegistry registry) {
    registry.addMapping("/**")
        .allowedOrigins("*")
        .allowedMethods("*")
        .allowedHeaders("*")
        .allowCredentials(true).maxAge(3600);
}

我用Google搜索并发现了这一点。

I googled around and found this.

如何在Spring Boot + Spring Security应用程序中配置CORS?

所以我添加了

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

我也找到了这个帖子。

I also found this thread.

Spring Data Rest和Cors

并尝试了以下代码,但没有运气。

and tried the following code as well, but no luck.

@Bean
public FilterRegistrationBean corsFilter() {
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    CorsConfiguration config = new CorsConfiguration();
    config.setAllowCredentials(true);
    config.addAllowedOrigin("*");
    config.addAllowedHeader("*");
    config.addAllowedMethod("OPTIONS");
    config.addAllowedMethod("HEAD");
    config.addAllowedMethod("GET");
    config.addAllowedMethod("PUT");
    config.addAllowedMethod("POST");
    config.addAllowedMethod("DELETE");
    config.addAllowedMethod("PATCH");
    source.registerCorsConfiguration("/**", config);
    // return new CorsFilter(source);
    final FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
    bean.setOrder(0);
    return bean;
}

我添加了一个catch all来测试哪个应该允许CORS明智地通过,然而,即使我有*,我仍然继续获得No'Access-Control-Allow-Origin'。

I added a catch all to test which should allow everything CORS wise to pass, however I still keep getting the No 'Access-Control-Allow-Origin' even though I have "*".

此时我不知道为什么预检请求没有通过访问控制检查我错过了什么。

At this point I have no idea what I am missing on why the preflight request doesn't pass access control check.

curl发出删除没有问题。

curl has no problem issuing the delete.

编辑:

结束找到确切的解决方案。我不确定我所拥有的和这种方法之间的区别,但这似乎有效。

Ended up finding the exact solution. I'm not sure of the differences between what I have and this method, but this seems to work.

import org.springframework.stereotype.Component;

import javax.servlet.*;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * Note this is a very simple CORS filter that is wide open.
 * This would need to be locked down.
 * Source: https://stackoverflow.com/questions/39565438/no-access-control-allow-origin-error-with-spring-restful-hosted-in-pivotal-web
 */
@Component
public class CORSFilter implements Filter {

    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        HttpServletResponse response = (HttpServletResponse) res;
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, OPTIONS, DELETE");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
        chain.doFilter(req, res);
    }

    public void init(FilterConfig filterConfig) {}

    public void destroy() {}

}


推荐答案

这是我用作所有CORS servlet过滤器的许可证:

This is what I use as a permit all CORS servlet filter:

public class PermissiveCORSFilter implements Filter {

    private static final Logger LOGGER = LoggerFactory.getLogger(PermissiveCORSFilter.class);
    private static final Pattern PATTERN = Pattern.compile("^[a-zA-Z0-9 ,-_]*$");

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        HttpServletResponse response = (HttpServletResponse) res;
        HttpServletRequest request = (HttpServletRequest) req;

        String origin;
        String credentialFlag;
        if (request.getHeader("Origin") == null) {
            origin = "*";
            credentialFlag = "false";
         } else {
            origin = request.getHeader("Origin");
            credentialFlag = "true";
         }

        // need to do origin.toString() to avoid findbugs error about response splitting        
        response.addHeader("Access-Control-Allow-Origin", origin.toString());
        response.setHeader("Access-Control-Allow-Credentials", credentialFlag);
        if ("OPTIONS".equals(request.getMethod())) {
            LOGGER.info("Received OPTIONS request from origin:" + request.getHeader("Origin"));
            response.setHeader("Access-Control-Allow-Methods", "GET,POST,HEAD,OPTIONS,PUT,DELETE");
            response.setHeader("Access-Control-Max-Age", "3600");
            String headers = StringUtils.trimToEmpty(request.getHeader("Access-Control-Request-Headers"));
            if (!PATTERN.matcher(headers).matches()) {
                throw new ServletException("Invalid value provided for 'Access-Control-Request-Headers' header");
            }
            response.setHeader("Access-Control-Allow-Headers", headers); // allow any headers
        }
        chain.doFilter(req, res);
    }

    @Override
    public void init(FilterConfig filterConfig) {
        // Do nothing
    }

    @Override
    public void destroy() {
        // Do nothing
    }

这篇关于没有为OPTIONS / DELETE正确启用Spring Boot Data Rest + CORS的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆