简体   繁体   中英

How to set CORS headers into internal server error responses?

I have a java application server with a REST interface provided by resteasy and I have the CORS filter bellow

@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");
    }

}

All requests return with the CORS headers:

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"

except when I have an internal exception that returns error code 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"

How can I make 500 responses contain those headers?

Use an 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();
    }

}

To avoid duplication of headers you should use:

cResp.getHeaders().putSingle() 

In the ContainerResponseFilter .

The ExceptionMapper will not work in all scenario's I've found. There seem to be some other container responses for which we need yet another filter type. Especially the response to requests to j_security_check (FORM login) don't get CORS headers added . So instead of using both a ContainerResponseFilter and an ExceptionMapper and still having some responses without CORS headers, I've opted for an Undertow filter. The downside is that it only works on Undertow-based servers (Jboss EAP, Wildfly, Wildfly Swarm), but the upside is that it works for all responses.

I wrote a specific filter for adding CORS headers that is installed as a JBoss Module and is configurable from standalone.xml . Find it here:

undertow-cors-filter

Download the .zip file and unzip it in your Wildfly root folder. Then add a filter configuration to 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>

Add a filter-ref to the host element (still in standalone.xml ):

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

This will add CORS headers allowing origins http(s)://(www.)example.(com|org) access to all responses for requests to URLs under path segment "/api" .

Change the param s in the filter definition to configure the behavior. There are 3 policy classes available, AllowAll , AllowMatching and Whitelist and you can write your own custom policies if needed.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM