【问题标题】:Jersey Client: Authentication fails at redirect by Jenkins泽西岛客户端:詹金斯重定向时身份验证失败
【发布时间】:2020-03-03 12:07:09
【问题描述】:

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

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

这对 Postman 来说效果很好(当然,除非我禁用“自动跟踪重定向”)。 然而,泽西岛在第 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);

编辑: 根据 Postman,“302-Found”只有 5 个标头:Date、X-Content-Type-Options (“nosniff”)、Location、Content-Length (0) 和服务器。因此,邮递员可能会使用任何 cookie 或任何令牌,泽西岛都不会忽视。

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

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

【问题讨论】:

  • 那么第一次认证后会发生什么,有没有发回的token或者cookie呢?您还没有真正解释身份验证部分如何使用 Postman 成功。
  • 嗨,保罗,我不确定我是否理解你对第二部分的意思,因为我对 REST 没有超级经验。如果这就是您的意思,授权类型是“基本身份验证”,只是用户名和密码。 (嗯,“密码”是在服务器上生成的令牌,但它仍然需要基本身份验证方式来授权......)我在帖子的响应中添加了详细信息 - 基本上响应只包含“日期,X-内容-类型选项、位置、内容长度、服务器”。所以很遗憾没有 cookie 或令牌。
  • 看起来泽西岛没有处理重定向。相反,较低级别的连接器处理它。例如,如果您使用默认的 HttpUrlConnection 连接器,它有一个方法可以设置您是否要遵循重定向,并且它从您设置的 Jersey 属性中获取该方法。 See here
  • 根据我提供的信息,从逻辑上讲,我看不出如果不按照您的建议手动完成这项工作。其他连接器具有相同的设置重定向选项。因此,要么编写自己的连接器,要么自己手动处理重定向。
  • 您如何验证第二个请求(重定向后)也是 POST ?似乎大多数互联网都适用于将第二个请求转换为 GET - 标头被丢弃。在这种情况下,您很可能会遇到您所面临的问题。您是否也尝试过http.strictPostRedirect=true 系统属性以查看它是否有效?

标签: jenkins jersey jax-rs jersey-client


【解决方案1】:

我在Paul SamsothaGautham的帮助下找到了答案。

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


正如here 所描述的那样,HttpURLConnection 决定不实现 HTTP 标准中定义的重定向,而是像许多浏览器一样实现它(所以用外行的话来说,“像其他人一样做,而不是怎么做应该工作”)。这会导致以下行为:

  1. 向 URL_1 发送 POST。
  2. 服务器以“302 - Found”回答并包括 URL_2。
  3. 将 GET 发送到 URL_2,删除所有标题
  4. 服务器回答“404 - 未找到”,因为第二个请求不包含正确的身份验证标头。
  5. “404”响应是代码收到的响应,因为步骤 2 和 3 被底层代码“隐藏”。

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

【讨论】:

    猜你喜欢
    • 2017-10-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-03
    • 1970-01-01
    • 1970-01-01
    • 2013-03-28
    • 2019-06-27
    相关资源
    最近更新 更多