Custom HTTP Header blocks Jersey CORS Filter
You need to understand how the CORS protocol works. For simple CORS requests, there is no preflight, and non-simple CORS requests, a preflight request is made. The preflight request is an OPTIONS request made prior to the actual request, asking the server if the request is allowed. This request is made with specific headers that the server should respond to with its own specific response headers. I mentioned all of this in the post you linked to. I even explained what each header is for.
The header in particular that is your problem is the preflight request header Access-Control-Request-Headers
. The browser will send this header (in the preflight request) and the value will list all of the headers the client is trying to set. The server should respond with a Access-Control-Allow-Headers
header that lists all of the headers that are allowed to be sent from the client. Any header that you want to allow the client to send should be listed in the value to this response header. For example
Access-Control-Allow-Headers: Authorization, xy
I also added a comment in the code telling you that you may need to change the list
response.getHeaders().add("Access-Control-Allow-Headers",
// Whatever other non-standard/safe headers (see list above)
// you want the client to be able to send to the server,
// put it in this list. And remove the ones you don't want.
"X-Requested-With, Authorization, " +
"Accept-Version, Content-MD5, CSRF-Token, Content-Type");
Please take time to review the entire post and read some of the resources that I linked to so you can fully understand how the CORS protocol works.
How to enable Cross domain requests on JAX-RS web services?
I was wondering the same thing, so after a bit of research I found that the easiest way was simply to use a JAX-RS ContainerResponseFilter
to add the relevant CORS headers. This way you don't need to replace the whole web services stack with CXF (Wildfly uses CXF is some form, but it doesn't look like it uses it for JAX-RS maybe only JAX-WS).
Regardless if you use this filter it will add the headers to every REST webservice.
package com.yourdomain.package;
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-Headers", "origin, content-type, accept, authorization");
cres.getHeaders().add("Access-Control-Allow-Credentials", "true");
cres.getHeaders().add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD");
cres.getHeaders().add("Access-Control-Max-Age", "1209600");
}
}
Then when I tested with curl, the response had the CORS headers:
$ curl -D - "http://localhost:8080/rest/test"
HTTP/1.1 200 OK
X-Powered-By: Undertow 1
Access-Control-Allow-Headers: origin, content-type, accept, authorization
Server: Wildfly 8
Date: Tue, 13 May 2014 12:30:00 GMT
Connection: keep-alive
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
Transfer-Encoding: chunked
Content-Type: application/json
Access-Control-Max-Age: 1209600
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS, HEAD
My understanding is that it's the @Provider
annotation that tells the JAX-RS runtime to use the filter, without the annotation nothing happens.
I got the idea about using the ContainerResponseFilter
from a Jersey example.
Jax-rs -jersey Cross Origin request enablement
Add this in your web.xml:
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>com.yigit.camp.api.MyAppConfig</param-value>
</init-param>
Then add this class:
package com.yigit.camp.api;
public class MyAppConfig extends Application {
@Override
public Set<Class<?>> getClasses() {
final Set<Class<?>> classes = new HashSet<Class<?>>();
classes.add(CORSResponseFilter.class);
return classes;
}
}
Now your response filter should be used.
Access-Control-Allow-Origin in ajax call to jersey rest web services
You have to use CORS.
For that:
- You have to use cors-filter jar
Then you have to use a filter in your web.xml :
<filter>
<filter-name>CORS</filter-name>
<filter-class>com.thetransactioncompany.cors.CORSFilter</filter-class>
<init-param>
<param-name>cors.allowGenericHttpRequests</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>cors.allowOrigin</param-name>
<param-value>*</param-value>
</init-param>
<init-param>
<param-name>cors.allowSubdomains</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>cors.supportedMethods</param-name>
<param-value>GET, HEAD, POST, OPTIONS</param-value>
</init-param>
<init-param>
<param-name>cors.supportedHeaders</param-name>
<param-value>Content-Type, X-Requested-With</param-value>
</init-param>
<init-param>
<param-name>cors.exposedHeaders</param-name>
<param-value>X-Test-1, X-Test-2</param-value>
</init-param>
<init-param>
<param-name>cors.supportsCredentials</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>cors.maxAge</param-name>
<param-value>-1</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CORS</filter-name>
<url-pattern>/EmployeeResource</url-pattern>
</filter-mapping>
Enable CORS Post Request from AngularJS to Jersey
The problem turned out to be inadequate handling of the OPTIONS request sent in pre-flight prior to the POST request with the proper cross origin headers.
I was able to resolve the issue by downloading and implementing the CORS filter found at this page: http://software.dzhuvinov.com/cors-filter-installation.html.
If you're experiencing a similar problem, follow the instructions and test to see that your OPTIONS request is no longer failing, and is immediately followed by your successful request.
How to allow multiple domains for CORS with ContainerResponseFilter in Jersy.?
Set the header value dynamically. Have a predefined list of origins you want to allow. In the filter method, grab the Origin
header from the request context. This will have the origin domain of the request. Check that against the list of allowed origins. If it's in the list, then put the domain from the Origin
header as the allowed origin. If it's not in there, throw a ForbiddenException
saying the origin is not allowed.
Related Topics
Resolving Dependency Problems in Apache Spark
How to Implement a Tree Data-Structure in Java
Selenium - Basic Authentication Via Url
Java: Recommended Solution For Deep Cloning/Copying an Instance
How to Format a Duration in Java (E.G Format H:Mm:Ss)
Sort on a String That May Contain a Number
How to Use Utf-8 in Resource Properties With Resourcebundle
Get Type of a Generic Parameter in Java With Reflection
Java Order of Initialization and Instantiation
What Are Functional Interfaces Used For in Java 8
How to Check If a File Exists in Java
Random Errors When Changing Series Using Jfreechart
Appending to an Objectoutputstream
How to Secure an API Rest For Mobile App (If Sniffing Requests Gives You the "Key")