Spring - Resteasy - Cors Double Access-Control-Allow-Origin标题作为回应

时间:2016-01-05 12:42:45

标签: spring cors resteasy

我使用Spring 3和Resteasy设置了一个Web应用程序;由于我的资源需要身份验证,因此我不允许使用*作为Access-Control-Allow-Origin。 所以我配置了

org.jboss.resteasy.plugins.interceptors.CorsFilter

使用正确的原始域名。 这适用于桌面客户端(Paw for Mac Os等),但不适用于浏览器(Chrome);问题是响应包含Access-Control-Allow-Origin的双精度值,即我配置的那个和'*'。

CorsFilter不应该受到责备,因为即使你配置了多个原点,它总是只为标题添加一个值,即请求所要求的值。

我根本不知道谁会把那个额外的(和错误的)标题,任何想法放在我能找到的地方? 请注意,双标头出现在GET请求上,但不出现在OPTIONS请求上。

4 个答案:

答案 0 :(得分:1)

我不确定您的双头标头来自哪里,但您是否尝试使用自定义过滤器? 例如:

@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class SimpleCorsFilter implements Filter {

public SimpleCorsFilter() {
}

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

        if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
            response.setStatus(HttpServletResponse.SC_OK);
        } else {
            chain.doFilter(req, res);
        }
    }

    @Override
    public void init(FilterConfig filterConfig) {
    }

    @Override
    public void destroy() {
    }

}

答案 1 :(得分:0)

我终于发现类路径中有一个专有的MessageBodyWriterInterceptor,它执行了错误的添加标头;现在,我删除它。 我学到的一件事是,如果只有在有一个正在写入的主体时才会发生某些事情,那么一个好的起点肯定是渲染管道

答案 2 :(得分:0)

我尝试了以下操作,它起到了魅力作用:

首先,在web.xml中注册CorsFilter提供程序类:

<context-param>
    <param-name>resteasy.providers</param-name>
    <param-value>org.jboss.resteasy.plugins.interceptors.CorsFilter</param-value>
</context-param>

通过这样做,您的服务器已经启用了处理CORS请求,但是,您需要添加一些允许的来源才能使其正常工作,因此,您应该可以访问由RestEasy创建的CorsFilter实例,然后添加所有您希望授予访问权限的URL,或者如果您希望授予对任何内容的访问权限,则添加*。

在这方面,如果您正在使用RestEasy Spring Integration,则需要通过将其自动装入代码中来获取org.jboss.resteasy.spi.ResteasyProviderFactory类的实例:

@Autowired
private ResteasyProviderFactory processor;

然后使用注释为@PostConstruct的设置方法从ResteasyProviderFactory获取CorsFilter的实例,如下面的代码段所示:

@PostConstruct
public void setUp() {
    ContainerRequestFilter[] requestFilters = processor.getContainerRequestFilterRegistry().preMatch();
    CorsFilter filter = (CorsFilter) Iterables.getLast(Iterables.filter(Arrays.asList(requestFilters), Predicates.instanceOf(CorsFilter.class)));
    filter.getAllowedOrigins().add("*");
}

P.S。:我正在使用这个框架:

  • Spring Framework 3.2.18.RELEASE
  • RestEasy 3.0.12.Final

我希望它有所帮助!

答案 3 :(得分:0)

对于那些像我这样没有使用应用程序启动程序但只使用Spring + Reasteasy的人。

只需添加web.xml:

<context-param>
    <param-name>resteasy.providers</param-name>
    <param-value>package.to.your.cors.CORSFilter</param-value>
</context-param>

并创建类似

的Java类CORSFilter
package package.to.your.cors;

import java.io.IOException;

import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerResponseContext;
import javax.ws.rs.container.ContainerResponseFilter;
import javax.ws.rs.ext.Provider;

@Provider
public class CORSFilter implements ContainerResponseFilter {

    @Override
    public void filter(final ContainerRequestContext requestContext,
                       final ContainerResponseContext cres) throws IOException {
        cres.getHeaders().add("Access-Control-Allow-Origin", "*");
        cres.getHeaders().add("Access-Control-Allow-Methods", "POST, GET, PUT, OPTIONS, DELETE");
        cres.getHeaders().add("Access-Control-Allow-Headers", "X-Auth-Token, Content-Type");
        cres.getHeaders().add("Access-Control-Max-Age", "4800");
    }

}

它就像一个魅力。

PS:受到筒嘴头答案的启发,但我无法评论他的答案,以添加我的详细信息。