Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JAX-RS enabling CORS (Access-Control-Allow-Origin) on Glassfish 4

I am working in JAVA EE7, JAX-RS 2.0 Glassfish 4 is my SERVER. I Want to work on CORS to enable Ajax Requests comming out of my domain. I know that I need to make my server enabling it. And I did it in PHP. like the following code:

 <?php header("Access-Control-Allow-Origin: *");
 header("Access-Control-Allow-Headers: Authorization");

but when I tried to do the same thing I always get an error message like that "this is a screenshot". So I've tried to modify the sever http response with many ways...

And this is my code , server side , I used a filer/provider:

@Provider
@CORSBinding 
public class Filter implements  ContainerRequestFilter{
@Override
public void filter(ContainerRequestContext request) throws IOException {
    request.getHeaders().add("Access-Control-Allow-Origin", "*");
    request.getHeaders().add("Access-Control-Allow-Headers", "Authorization"); 
    if (request.getMethod().equals("OPTIONS")) {
        System.out.println("OPTIONS is requested!!!!!!!!!!!!!");
    }
    if (request.getMethod().equals("GET")) {
        System.out.println("GET is requested!!!!!!!!!!!!!");
    }
    if (request.getMethod().equals("POST")) {
        System.out.println("POST is requested!!!!!!!!!!!!!");
    }
    if (request.getMethod().equals("DELETE")) {
        System.out.println("DELETE is requested!!!!!!!!!!!!!");
    }
    if (request.getMethod().equals("PUT")) {
        System.out.println("PUT is requested!!!!!!!!!!!!!");
    }       
}
}

But it seems like all blocked by a "firewall security" provided by Glassfish4 server. here is my simple code javascript:

<script>
var xhr = new XMLHttpRequest();
xhr.open("POST", "http://127.0.0.1:8080/CV/api/v2/posts");
xhr.setRequestHeader('Authorization', 'a');
xhr.send();
</script>

I even added an other filter using the @Prematching annotation to update the request from OPTIONS TO POST ... but I always lose my headers that I have sent within it (I mean within POST request).

@Provider
@PreMatching
 public class HttpMethodOverrideEnabler implements ContainerRequestFilter {
 @Override
 public void filter(ContainerRequestContext containerRequestContext) throws IOException {
    containerRequestContext.setMethod("POST");

    containerRequestContext.getHeaders().add("Access-Control-Allow-Origin", "*");
    containerRequestContext.getHeaders().add("Access-Control-Allow-Headers","Authorization");
    containerRequestContext.getHeaders().add("Access-Control-Allow-Headers","Authorization");

    String override = containerRequestContext.getHeaders().getFirst( "X-HTTP-Method-Override");
    if (override != null) {
        containerRequestContext.setMethod(override);
    }
}

I knew that Glassfish3 had not the support for CORS and ("https://java.net/jira/browse/GLASSFISH-16049) they said that they will fix it with JEE7. This is the whole story... so how can I do the CORS with this JEE7 using Glassfish server and JAX-RS2. Thanks in advance.

like image 349
AndroidLover Avatar asked Nov 25 '13 16:11

AndroidLover


People also ask

How to enable CORS in JAX-RS?

There are two ways by which we can enable CORS in JAX-RS. The first and the most basic way is to create a filter to inject necessary response header at run-time in every request. The other one is to manually add an appropriate header in each URL endpoint.

How do I enable CORS?

Simply add a header to your HttpServletResponse by calling addHeader : response. addHeader("Access-Control-Allow-Origin", "*");

What is allowed origin in Cors?

Cross-Origin Resource Sharing (CORS) is an HTTP-header based mechanism that allows a server to indicate any origins (domain, scheme, or port) other than its own from which a browser should permit loading resources.

What is CORS in JAva?

Cross-Origin Resource Sharing (CORS) is a security concept that allows restricting the resources implemented in web browsers. It prevents the JavaScript code producing or consuming the requests against different origin.


2 Answers

Use ContainerResponseFilter not ContainerRequestFilter as you want to add those headers into response and not to the request. For example:

@Provider
@Priority(Priorities.HEADER_DECORATOR)
public class AccessControlResponseFilter implements ContainerResponseFilter {

    @Override
    public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException {
        final MultivaluedMap<String,Object> headers = responseContext.getHeaders();

        headers.add("Access-Control-Allow-Origin", "*");
        headers.add("Access-Control-Allow-Headers", "Authorization, Origin, X-Requested-With, Content-Type");
        headers.add("Access-Control-Expose-Headers", "Location, Content-Disposition");
        headers.add("Access-Control-Allow-Methods", "POST, PUT, GET, DELETE, HEAD, OPTIONS");
    }
}
like image 51
Michal Gajdos Avatar answered Nov 13 '22 04:11

Michal Gajdos


You have to use the 2 *filters* the First because Chrome and other Browsers modify the headers for security purpose, and the second is to add the headers to response. So use ContainerResponseFilter and ContainerRequestFilter. it works fine with me Good luck!

like image 28
user3013507 Avatar answered Nov 13 '22 02:11

user3013507