【问题标题】:Jersey filter does not give header values泽西过滤器不提供标题值
【发布时间】:2018-10-18 07:40:19
【问题描述】:

我们将 jersey 2 用于 Java 中的 REST Web 服务。 我们创建了javax.ws.rs.container.ContainerRequestFilterjavax.ws.rs.container.ContainerResponseFilter

在发送 appKey、secret、token 等请求时,我们有标头。 如果我们从 Postman 发出请求,它会给出所有标头及其值,如下所示:

{
  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]
}

如果我们从网络客户端发出请求,它会在access-control-request-headers 下给出如下值(只有键,而不是它们的值):

{
  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]
}

为什么它不给头参数值?

如何获得这些?

请指导我。 提前致谢!

【问题讨论】:

    标签: java rest web-services jersey-2.0


    【解决方案1】:

    首先,这些是您正在显示的 request 标头,而不是 response 标头,您似乎在说它们是。

    您在此处显示的是来自 CORS preflight 请求的标头,而不是实际请求。预检请求是浏览器在实际请求之前执行的请求,与服务器验证该请求是否被允许。如果预检被批准,那么将提出真正的请求。在预检中,浏览器询问服务器是否允许这些列出的标头。这是在请求标头access-control-request-headers 中。同样,它使用access-control-request-method 询问服务器是否允许GET 方法调用。

    在对 CORS 预检请求的响应中,服务器应使用标头响应那些确认该请求是可接受的。响应应包含以下标头

    • Access-Control-Allow-Origin - 这是对Origin 预检请求标头的响应。该值应包括 Origin 的值或 * 以允许所有来源。这告诉浏览器来源是允许的。

    • Access-Control-Allow-Headers - 这是对access-control-request-headers 预检请求标头的响应。该值应该是一个逗号分隔的列表,至少包含浏览器请求的所有标头。如果缺少其中任何一个,预检请求将失败。

    • Access-Control-Allow-Methods - 这是对access-control-request-method 预检请求标头的响应。该值至少应该是请求的方法,或者通常是允许的方法列表。

    如果您查看this post,您会看到ContainerResponseFilter 用于通过添加所有必需的标头以通过预检验证来处理此预检请求的返回。

    @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");
        }
    }
    

    在您的情况下,您可能希望将标题 x-api-key,x-api-secret,x-request-id 添加到 Access-Control-Allow-Headers 的列表中。这些值告诉浏览器可以发送这些标头。

    预检请求成功后,浏览器将发送实际请求。如果预检失败,通常浏览器会提示您哪些验证失败。

    【讨论】:

    • 感谢您的回答!我们遇到了另一个问题,我在以下链接中发布了新问题:[stackoverflow.com/questions/50250401/… 请查看并帮助我们!
    • 我有一个非常相似的问题,只是略有不同,我们在 ContainerRequestFilter 中根据标头参数('x-api-key'等)对客户端进行身份验证,如果没有则中止请求- 认证。
    猜你喜欢
    • 2015-09-13
    • 1970-01-01
    • 2014-02-10
    • 2011-08-17
    • 1970-01-01
    • 2014-08-21
    • 2013-06-21
    • 1970-01-01
    相关资源
    最近更新 更多