如何将CORS标头设置为内部服务器错误响应?

时间:2015-01-15 16:28:18

标签: java jax-rs cors resteasy

我有一个带有REST接口的java应用服务器,由resteasy提供,我有CORS过滤器

@Provider
public class CORSFilter implements ContainerResponseFilter {

    public void filter(ContainerRequestContext cReq, ContainerResponseContext cResp) {
        cResp.getHeaders().add("Access-Control-Allow-Origin", "*");
        cResp.getHeaders().add("Access-Control-Allow-Headers", "origin, content-type, accept, authorization, auth-token");
        cResp.getHeaders().add("Access-Control-Allow-Credentials", "true");
        cResp.getHeaders().add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD");
        cResp.getHeaders().add("Access-Control-Max-Age", "1209600");
    }

}

所有请求都返回CORS标头:

OPTIONS 200 OK
Access-Control-Allow-Credentials:"true"
Access-Control-Allow-Headers:"origin, content-type, accept, authorization, auth-token"
Access-Control-Allow-Methods:"GET, POST, PUT, DELETE, OPTIONS, HEAD"
Access-Control-Allow-Origin:"*"
Access-Control-Max-Age:"1209600"
Allow:"HEAD, GET, OPTIONS"
Connection:"keep-alive"
Content-Length:"18"
Content-Type:"text/plain"
Date:"Thu, 15 Jan 2015 15:23:01 GMT"
Server:"WildFly/8"

除非我有一个返回错误代码500的内部异常:

GET 500 Internal Server Error
Connection:"keep-alive"
Content-Length:"8228"
Content-Type:"text/html; charset=UTF-8"
Date:"Thu, 15 Jan 2015 15:23:01 GMT"

如何让500个回复包含这些标题?

2 个答案:

答案 0 :(得分:3)

使用ExceptionMapper

@Provider
public class CorsExceptionMapper implements ExceptionMapper<Exception> {

    @Override
    public Response toResponse(Exception ex) {
        ResponseBuilder responseBuilder = Response.serverError();
        responseBuilder.header("Access-Control-Allow-Origin", "*");
        responseBuilder.header("Access-Control-Allow-Headers", "origin, content-type, accept, authorization, auth-token");
        responseBuilder.header("Access-Control-Allow-Credentials", "true");
        responseBuilder.header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD");
        responseBuilder.header("Access-Control-Max-Age", "1209600");
        return responseBuilder.build();
    }

}

为避免重复标题,您应该使用:

cResp.getHeaders().putSingle() 

ContainerResponseFilter

答案 1 :(得分:0)

ExceptionMapper不适用于我找到的所有场景。似乎还有一些其他容器响应,我们还需要另一种过滤器类型。特别是对j_security_check(FORM登录)don't get CORS headers added的请求的响应。因此,我没有同时使用ContainerResponseFilterExceptionMapper并且仍然有一些没有CORS标头的响应,而是选择了Undertow过滤器。缺点是它只适用于基于Undertow的服务器(Jboss EAP,Wildfly,Wildfly Swarm),但优点是它适用于所有响应。

我编写了一个特定的过滤器,用于添加作为JBoss模块安装的CORS头,可以从standalone.xml配置。在这里找到它:

undertow-cors-filter

下载.zip文件并将其解压缩到Wildfly根文件夹中。然后将filter配置添加到standalone.xml

<filters>
  <filter name="undertow-cors-filter" class-name="com.stijndewitt.undertow.cors.Filter" module="com.stijndewitt.undertow.cors">
    <param name="urlPattern" value="^http(s)?://([^/]+)(:([^/]+))?(/([^/])+)?/api(/.*)?$" />
    <param name="policyClass" value="com.stijndewitt.undertow.cors.AllowMatching" />
    <param name="policyParam" value="^http(s)?://(www\.)?example\.(com|org)$" />   
  </filter>
</filters>

filter-ref添加到host元素(仍在standalone.xml中):

<host name="default-host" alias="localhost">
  <filter-ref name="undertow-cors-filter" />
</host>

这将添加CORS标头,允许来源http(s)://(www.。)示例。(com | org)访问路径段"/api"下的URL请求的所有响应。

更改param定义中的filter以配置行为。有3个策略类可用,AllowAllAllowMatchingWhitelist,您可以根据需要编写自己的自定义策略。