问题
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?
回答1:
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
.
回答2:
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.
来源:https://stackoverflow.com/questions/27968190/how-to-set-cors-headers-into-internal-server-error-responses