Search code examples
jerseycors

Jersey - Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin'


Error Screenshot :

enter image description here

The following is my API class in which I have written code for @OPTIONS method.

@OPTIONS 
    public Response OptionsFirstRequst(){
         return Response.ok()
      .header("Access-Control-Allow-Origin", "*")
      .header("Access-Control-Allow-Methods", "*")
      .header("Access-Control-Allow-Headers", "*").build();
    }

I have created a class called Response Builder using which for each request I send response. The following is the code for the Response Builder class:

    public class ResponseBuilder {

    public int status;
    public HashMap data;
    public String error;

    public static Response ok(int Status_code, HashMap<String, String> data, String Response_error) {
        if (data == null) {
            data = new HashMap();
        }

        ResponseBuilder response = new ResponseBuilder();
        response.status = Status_code;
        response.data = data;
        response.error = Response_error;

        return Response.status(Status_code).entity(response)
                .header("Access-Control-Allow-Origin", "*")
                .header("Access-Control-Allow-Methods", "*")
                .header("Access-Control-Allow-Headers", "*").build();
    }

    public static Response error(int Status_code, HashMap<String, String> data, String Response_error) {
        if (data == null) {
            data = new HashMap();
        }

        ResponseBuilder response = new ResponseBuilder();
        response.status = Status_code;
        response.data = data;
        response.error = Response_error;
        response.data = new HashMap();

        return Response.status(Status_code).entity(response)
                .header("Access-Control-Allow-Origin", "*")
                .header("Access-Control-Allow-Methods", "*")
                .header("Access-Control-Allow-Headers", "*").build();
    }

}

I also have a Request filter which validates token for each request , except for login.

I am able to login , generate token and give it back to the browser. But after login if I click on profile.

I get response as 200 (as shown in the dev-tools network of the browser) , but I am not getting any data/correct response.

And I am getting the following error.

Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.


Solution

  • To check and add CORS headers, a common solution is to use a javax.ws.rs.container.ContainerResponseFilter. Here an example, where the allowed origins are configured in a class ApplicationConfig.accessControlAllowedOrigins:

    import javax.ws.rs.container.ContainerRequestContext;
    import javax.ws.rs.container.ContainerResponseContext;
    import javax.ws.rs.container.ContainerResponseFilter;
    import javax.ws.rs.core.MultivaluedMap;
    import javax.ws.rs.ext.Provider;
    import java.io.IOException;
    
    @Provider
    public class ResponseCorsFilter implements ContainerResponseFilter {
    
        @Override
        public void filter(ContainerRequestContext requestContext, 
                ContainerResponseContext responseContext) throws IOException {
    
            MultivaluedMap<String, Object> responseHeaders = responseContext.getHeaders();
            String origin = requestContext.getHeaderString("Origin");
            if (null != origin && 
                (ApplicationConfig.accessControlAllowedOrigins.contains(origin) ||
                     ApplicationConfig.accessControlAllowedOrigins.contains("*"))) {
    
                responseHeaders.putSingle("Access-Control-Allow-Origin", origin);
                responseHeaders.putSingle("Access-Control-Allow-Methods", 
                    "GET, POST, OPTIONS, PUT, DELETE, HEAD");
    
                String reqHead = requestContext.getHeaderString(
                    "Access-Control-Request-Headers");
    
                if (null != reqHead && !reqHead.equals("")) {
                    responseHeaders.putSingle("Access-Control-Allow-Headers", reqHead);
                }
            }
        }
    }