Jersey 客户端:Jenkins 重定向时身份验证失败

Jersey Client: Authentication fails at redirect by Jenkins

我正在尝试使用 Jenkins 的 REST api。 Jenkins 需要 POST 请求 URL 来删除作业。结果如下:

  1. 我告诉我选择的客户发送 POST 到适当的 URL。
    客户端发送 POST 并使用用户名和密码对自己进行授权。
  2. Jenkins 删除作业。
  3. Jenkins returns 一个“302 - 找到”,其中包含包含已删除作业的文件夹的位置。
  4. 客户端自动发送 POST 到该位置。
  5. Jenkins 回答“200 - OK”和文件夹页面的完整 HTML。

这对 Postman 来说工作得很好(当然,除非我禁用 "Automatically follow redirects")。 然而,Jersey 在第 5 步将 运行 保留为“404”,因为我阻止了匿名用户查看相关文件夹。 (如果我完全阻止匿名用户,则为“403”。) 请注意,身份验证在步骤 1 中有效,因为作业已成功删除!

我的印象是 Jersey 应该对与客户端有关的所有请求使用给定的身份验证。 有没有办法真正做到这一点?我真的不想为了自己做每一个重定向而禁止重定向。

澄清一下:问题在于,虽然 Jersey 遵循了重定向,但未能再次验证自身,导致服务器拒绝了第二个请求。

有问题的代码:

HttpAuthenticationFeature auth = HttpAuthenticationFeature.basicBuilder()
    .credentials(username, token)
    .build();
Client client = ClientBuilder.newBuilder()
    .register(auth)
    .build();
WebTarget deleteTarget = client.target("http://[Jenkins-IP]/job/RestTestingArea/job/testJob/doDelete")  
Response response = deleteTarget.request()
    .post(null);

编辑: 根据邮递员的说法,“302-Found”只有 5 个 headers:日期,X-Content-Type-Options("nosniff"),位置,Content-Length (0) 和服务器。因此,无论是 Postman 可能使用的任何 cookie 还是任何标记,Jersey 都不会忽略。

问题与 this one 松散相关 - 如果我能够记录第二个请求,我也许能够了解幕后发生的事情。

EDIT2: 我还确定问题显然出在身份验证上。如果我允许匿名用户查看有问题的文件夹,错误就会消失,服务器会回复 200。

我在 Paul Samsotha and Gautham 的帮助下找到了答案。

TL;DR: 这是预期行为,您必须设置系统 属性 http.strictPostRedirect=true 才能使其工作 自己执行第二个请求。


正如 here 所述,HttpURLConnection 决定不实施重定向,因为它在 HTTP 标准中定义,而是许多浏览器都实施了重定向(所以在外行人看来,"Do it like everyone else instead of how it is supposed to work").这会导致以下行为:

  1. 发送 POST 到 URL_1。
  2. 服务器回答“302 - 已找到”并包括 URL_2。
  3. 发送 GET 到 URL_2,丢弃 所有 headers
  4. 服务器以“404 - 未找到”作为响应,因为第二个请求未包含正确的身份验证 headers。
  5. “404”响应是代码收到的响应,因为底层代码 "hidden" 步骤 2 和步骤 3。

通过删除所有 headers,身份验证失败。由于 Jersey 默认使用此 class,这导致了我遇到的行为。