Not able to receive header parameter in ContainerRequestFilter

Ahsan Saeed :

I'm creating web-services in Java with Jersey2.0. Everything works as expected when I execute request from POSTMAN but when I execute request from the client application I'm not able to receive header parameter. My client application is on JavaScript. Also, I've added the CORS allows origin request parameters in ContainerResponseContext.

The following shows my ContainerResponseFilter class where I add the CORS.

@Provider
class CORSFilter : ContainerResponseFilter {

    override fun filter(requestContext: ContainerRequestContext?, responseContext: ContainerResponseContext?) {
        responseContext?.apply {
            headers.add("Access-Control-Allow-Origin", "*")
            headers.add("Access-Control-Allow-Headers", "origin, content-type, authorization, accept, privatekey")
            headers.add("Access-Control-Allow-Credentials", "true")
            headers.add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD")
        }
    }
}

The privatekey is my header name for the request. Now here's my code for ContainerRequestFilter.

@Priority(AUTHENTICATION)
@Provider
class JsTokenFilterNeeded : JsBaseFilter(this::class.java.simpleName) {

    override fun filter(request: ContainerRequestContext?) {
        val path = request?.uriInfo?.path       
        val privateKeyHeaderValue = request?.getHeaderString("privatekey")
        println("private key -> $privateKeyHeaderValue")
    }
}

I'm always getting the null value in privateKeyHeaderValue. Both the containers are successfully registered in ResourceConfig class.

As of now, I'm getting no 'Access-Control-Allow-Origin' header is present on the requested resource here's the log.

{host=[203.***.51.***:5555], connection=[keep-alive], access-control-request-method=[GET], origin=[http://localhost:38596], user-agent=[Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36], access-control-request-headers=[privatekey], accept=[*/*], alexatoolbar-alx_ns_ph=[AlexaToolbar/alx-4.0.3], referer=[http://localhost:38596/], accept-encoding=[gzip, deflate], accept-language=[en-US,en;q=0.9]}

Edit 1 Here's my Js code for the client application.

$.ajax(
    {
        type: "GET",
        headers: {
            'privatekey': privateKey
        },
        url: "http://***.124.**.76:5555/dcu/energy/"+active_import,
        data: {
            'dcu_id': '99220445',
            'tariff': 0
        },
        error: function (result) {
            console.log(result);
        },
        success: function (result) {
            console.log(result);
        }
    });

Edit2 I'm using ResourceConfig in order to register my Providers. Here's my ResourceConfig class.

class MyResourceConfig : ResourceConfig() {

    init {
        register(CORSFilter())
        register(JsTokenFilterNeeded())
    }
}
Paul Samsotha :

There is a preflight request that happened before the real request. The preflight request doesn't send any of the headers (the key header included). It only sends headers asking the server if the request is allowed. So when the preflight request reaches the filter, the token will not be there.

What you should do is make the CorsFilter implement both a ContainerRequestFilter and a ContainerResponseFilter. Make it a @PreMatching filter. That way it will be called before the token filter. In the request filter, check to see if it is a preflight request. If it is, then abort the request. This will cause the request to skip the rest of the request filters and go straight to the response filters. In the response filter side, you can add the CORS headers.

You should read the UPDATE in this post to get a better understanding of the flow of the CORS protocol and also see a better implementation of the CorsFilter that you can use that should work for your scenario.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=149800&siteId=1