我想调用需要基本身份验证的Web服务。我不能使用抢占式身份验证,因为该服务返回带有特定cookie的代码401。此Cookie必须与基本auth标头一起在响应中发送。以下代码不起作用:
CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
Credentials credentials = new UsernamePasswordCredentials("user", "password");
credentialsProvider.setCredentials(AuthScope.ANY, credentials);
RequestConfig requestConfig = RequestConfig.custom()
.setCookieSpec(CookieSpecs.DEFAULT)
.build();
HttpClient httpClient = HttpClientBuilder.create()
.setDefaultCredentialsProvider(credentialsProvider)
.setDefaultRequestConfig(requestConfig)
.build();
HttpGet get = new HttpGet("https://a.something.com/something");
try {
HttpResponse response = httpClient.execute(get);
System.out.println(response.getStatusLine());
} catch (IOException e) {
e.printStackTrace();
}
在日志中,我可以看到HttpClient对代码401做出了响应,并且它正在使用基本身份验证数据第二次发送请求。但是缺少cookie:
http-outgoing-0 >> "GET /something HTTP/1.1[\r][\n]"
http-outgoing-0 >> "Host: a.something.com[\r][\n]"
http-outgoing-0 >> "Connection: Keep-Alive[\r][\n]"
http-outgoing-0 >> "User-Agent: Apache-HttpClient/4.5.5 (Java/1.8.0_172)[\r][\n]"
http-outgoing-0 >> "[\r][\n]"
http-outgoing-0 << "HTTP/1.1 401 Unauthorized[\r][\n]"
http-outgoing-0 << "WWW-authenticate: basic realm="XXXXXX"[\r][\n]"
http-outgoing-0 << "Set-Cookie: SMCHALLENGE=YES; path=/; domain=.something.com; secure; HTTPOnly[\r][\n]"
http-outgoing-0 >> "GET /something HTTP/1.1[\r][\n]"
http-outgoing-0 >> "Host: a.something.com[\r][\n]"
http-outgoing-0 >> "Connection: Keep-Alive[\r][\n]"
http-outgoing-0 >> "User-Agent: Apache-HttpClient/4.5.5 (Java/1.8.0_172)[\r][\n]"
http-outgoing-0 >> "Authorization: Basic xxxxxxxxxxxxxxx[\r][\n]"
http-outgoing-0 >> "[\r][\n]"
http-outgoing-0 << "HTTP/1.1 403 Forbidden[\r][\n]"
在此循环中,请求第一次执行。然后,在第293行中,方法“ needsAuthentication()”返回true,并且第二次执行该请求。但是我看不到,应该将第一个响应中的cookie复制到第二个请求中。
答案 0 :(得分:0)
研究了MainClientExec.java
(参见上文)之后,我认为这是一个错误或者根本不是受支持的功能:Apache HttpClient不会在“ 401”重试中设置cookie。