带有身份验证的 okhttp 发布请求

Posted

技术标签:

【中文标题】带有身份验证的 okhttp 发布请求【英文标题】:okhttp post request with authentication 【发布时间】:2020-07-10 14:07:17 【问题描述】:

我正在使用 okhttp (4.4.0) java 库向我创建的 Web 服务发送发布请求。 此外,该 Web 服务需要基本身份验证,并且只接受后请求。 Web 服务位于一个代理后面,该代理只是将 https 请求转发到端口 8080 上的 http 请求。 我的代码如下所示:

    ...
    RequestBody formBody = new FormBody.Builder()
                        .add("foo", this.foo)
                        .add("bar", this.bar)
                        .build();

    Request request = new Request.Builder()
                        .url("https://localhost/myWebApp")
                        .addHeader("User-Agent", "OkHttp Bot")
                        .addHeader("Authorization", Credentials.basic("myUser", "myPwd"))
                        .post(formBody)
                        .build();
    try (Response response = client.newCall(request).execute()) 
      if (!response.isSuccessful()) 
        throw new IOException("Unexpected code " + response);
      
      return response.body().bytes();
     catch (IOException e) 
      e.printStackTrace();
    
    ...

请求失败并出现以下错误:

Unexpected code Responseprotocol=http/1.1, code=501, message=Not Implemented, url=https://localhost/myWebApp/

Web 服务的“myWebApp”doGet 方法配置为发送 501 未实现状态消息。 但是当我做一个后请求时,不应该调用 doGet 方法。

通过查看我的网络服务器的访问日志,我发现以下内容:

    127.0.0.1 - - [30/Mar/2020:09:05:24 +0200] "POST /myWebApp HTTP/1.1" 302 -
    127.0.0.1 - myUser [30/Mar/2020:09:05:25 +0200] "GET /myWebApp/ HTTP/1.1" 501 1029

所以有一个发布请求和一个获取请求。 看起来首先尝试发送帖子正文(没有身份验证?),然后是我的网络服务拒绝的带有身份验证的获取请求。

有没有办法让这个工作适合我?我错过了什么吗?请帮忙!

【问题讨论】:

能分享一下代理配置吗?那里可能有什么东西。 这是相当标准的 apache ssl.conf。我刚刚在虚拟主机部分添加了这几行ProxyRequests Off ProxyPreserveHost On ProxyPass /MyWebApp http://localhost:8080/MyWebApp ProxyPassReverse /myWebApp http://localhost:8080/MyWebApp 【参考方案1】:

您的服务器应返回 401 质询,以供客户端进行身份验证。但由于某种原因正在发送 302。是否设置为具有自定义登录页面的浏览器中的用户重定向?

见https://github.com/square/okhttp/blob/master/samples/guide/src/main/java/okhttp3/recipes/Authenticate.java

【讨论】:

我也想知道这一点。我运行了链接的示例代码,它产生了以下输出:Authenticating for response: Responseprotocol=http/1.1, code=401, message=Unauthorized, url=https://localhost/MyWebApp/ Challenges: [Basic authParams=realm=Authentication required] Exception in thread "main" java.io.IOException: Unexpected code Responseprotocol=http/1.1, code=501, message=Not Implemented, url=https://localhost/MyWebApp/ at Authenticate.run(Authenticate.java:39) at Authenticate.main(Authenticate.java:46) 访问日志如下:127.0.0.1 - - [31/Mar/2020:07:18:51 +0200] "GET /MyWebApp HTTP/1.1" 302 - 127.0.0.1 - - [31/Mar/2020:07:18:51 +0200] "GET /MyWebApp/ HTTP/1.1" 401 994 127.0.0.1 - myUser [31/Mar/2020:07:18:51 +0200] "GET /MyWebApp/ HTTP/1.1" 501 1029【参考方案2】:

看来我解决了自己的问题。感谢@Yuri 指向我那里。 我刚刚在我的代码中的 url 末尾添加了一个“/”,它就像一个魅力。

...
 Request request = new Request.Builder()
                        .url("https://localhost/myWebApp/")
                        .addHeader("User-Agent", "OkHttp Bot")
                        .addHeader("Authorization", Credentials.basic("myUser", "myPwd"))
                        .post(formBody)
                        .build();
...

出于某种原因(我还不知道,但也许其他人可以启发我)任何不带斜杠的给定 url 都会被重定向到带有斜杠的相同 url。 标准浏览器可以处理这种情况,okhttp 客户端似乎很难解决。

【讨论】:

以上是关于带有身份验证的 okhttp 发布请求的主要内容,如果未能解决你的问题,请参考以下文章

如何在okhttp3身份验证器中使用具有异步请求的刷新令牌添加身份验证

okHttp 3.x身份验证器未被调用

带有请求承诺的 NodeJS 发布请求以进行 Twitch 身份验证

具有基本身份验证的 Android OkHttp

带有标头和身份验证的 npm 请求

Amazon S3 是不是支持带有基本身份验证的 HTTP 请求