Jersey filter does not give header values

2020-03-31 08:46发布

问题:

We are using jersey 2 for our REST web services in Java. We have created the javax.ws.rs.container.ContainerRequestFilter and javax.ws.rs.container.ContainerResponseFilter

We have headers while sending a request like appKey, secret, token etc. If we hit a request from Postman, it gives all the header with their values as follows:

{
  host=[localhost:8080], 
  connection=[keep-alive], 
  authorization=[bearer <token>], 
  cache-control=[no-cache],  
  x-request-id=[<request-id>], 
  x-api-secret=[<secret>], 
  user-agent=[Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.162 Safari/537.36], 
  x-api-key=[api-key], 
  postman-token=[<postman-token>], 
  accept=[*/*], 
  accept-encoding=[gzip, deflate, br], 
  accept-language=[en-US,en;q=0.9]
}

and if we hit a request from our web client, it gives values under access-control-request-headers as follows (only keys, not their values):

{
  host=[localhost:8080], 
  connection=[keep-alive], 
  access-control-request-method=[GET], 
  origin=[http://resttesttest.com], 
  user-agent=[Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.162 Safari/537.36], 
  access-control-request-headers=[authorization,x-api-key,x-api-secret,x-request-id], 
  accept=[*/*],
  accept-encoding=[gzip, deflate, br],
  accept-language=[en-US,en;q=0.9]
}

why it does not give header parameters values?

How to get those?

Please guide me on this. Thanks in advance!

回答1:

Firstly, these are request headers you are showing, not response headers, which it seems like you are saying they are.

What you are showing here are the headers from the CORS preflight request, not the actual request. The preflight request is a request that the browser performs before the actual request, verifying with the server that the request is allowed. If the preflight is approved, then the real request will be made. In the preflight, the browser is asking the server if it will allow those listed headers. This is in the request header access-control-request-headers. Similarly it uses the access-control-request-method to ask the server if it will allow GET method calls.

In the response to the CORS preflight request, the server should respond with headers to those confirm that the request is acceptable. The response should include the following headers

  • Access-Control-Allow-Origin - this is in response to the Origin preflight request header. The value should include the value of the Origin or * to allow all origins. This tells the browser that the origin is allowed.

  • Access-Control-Allow-Headers - this is in response to the access-control-request-headers preflight request header. The value should be a comma separated list of at least all the headers that the browser requested. If any of them are missing, the the preflight request will fail.

  • Access-Control-Allow-Methods - this is in response to the access-control-request-method preflight request header. The value should be at least the method requested, or usually a list of methods allowed.

If you look at this post, you will see that a ContainerResponseFilter is used to handle the return of this preflight request by adding all the required headers to pass the preflight verification.

@Provider
public class CORSFilter implements ContainerResponseFilter {

    @Override
    public void filter(ContainerRequestContext request,
                       ContainerResponseContext response) throws IOException {

        response.getHeaders().add("Access-Control-Allow-Origin", "*");
        response.getHeaders().add("Access-Control-Allow-Headers",
                "origin, content-type, accept, authorization");
        response.getHeaders().add("Access-Control-Allow-Credentials", "true");
        response.getHeaders().add("Access-Control-Allow-Methods",
                "GET, POST, PUT, DELETE, OPTIONS, HEAD");
    }
}

In your case, you would want to add the headers x-api-key,x-api-secret,x-request-id to the list in the Access-Control-Allow-Headers. These values tell the browser that it is OK to send these headers.

After the preflight request is a success, then the browser will send the actual request. If the preflight failed, then usually the browser will give you a hint as to which verifications failed.