使用Basic Auth时,HTTPClient会发出两个请求吗?

dav*_*lab 13 java basic-authentication apache-httpclient-4.x

我一直在使用HTTPClient版本4.1.2来尝试访问需要基本身份验证的REST over HTTP API.这是客户端代码:

DefaultHttpClient httpClient = new DefaultHttpClient(new ThreadSafeClientConnManager());
// Enable HTTP Basic Auth
httpClient.getCredentialsProvider().setCredentials(
    new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT), 
    new UsernamePasswordCredentials(this.username, this.password));

HttpHost proxy = new HttpHost(this.proxyURI.getHost(), this.proxyURI.getPort());

httpClient.getParams().setParameter(ConnRouteParams.DEFAULT_PROXY, proxy);
Run Code Online (Sandbox Code Playgroud)

当我构造一个POST请求时,像这样:

HttpPost request = new HttpPost("http://my/url");
request.addHeader(new BasicHeader("Content-type", "application/atom+xml; type=entry")); // required by vendor
request.setEntity(new StringEntity("My content"));

HttpResponse response = client.execute(request);
Run Code Online (Sandbox Code Playgroud)

我在Charles Proxy中看到有两个请求被发送.一个没有Authorization: Basic ...头和一个它.正如你所料,第一个失败的是401,但是第二个失败的是201.

有谁知道为什么会这样?谢谢!

编辑:

我应该明确表示我已经看过这个问题,但正如你所看到的那样,我设置的AuthScope方式相同而且没有解决我的问题.此外,我HttpClient每次发出请求时都会创建一个新的(虽然我使用相同的ConnectionManager),但即使我HttpClient对多个请求使用相同的内容,问题仍然存在.

编辑2:

所以看起来@LastCoder的建议就是这样做的.看到另一个问题的答案.问题源于我对HTTP规范缺乏了解.我想要做的是"抢先认证",HttpClient 文档在这里提到它.值得庆幸的是,与上述相关的答案是一种更简洁,更简洁的方法.

Lou*_*cci 11

而不是使用.setCredentials()为什么不编码USERNAME:PASSWORD并使用.addHeader()添加身份验证标头

  • @daveslab - 这是http客户端规范的一部分,首先匿名请求资源并使用Authorization标头响应401.如果不是客户端会使用授权标头凭据向Web服务器发送垃圾邮件,则Web服务器甚至不需要.这只是基本的安全最佳实践. (7认同)