使用凭证提供者时,Apache HttpClient不发送身份验证标头

时间:2018-12-08 21:21:38

标签: java apache-httpclient-4.x

编辑:我已经尝试过注释中提供的解决方案,但是它们不起作用。添加原始标头是可行的,但是我试图避免这样做。

我正面临一个奇怪的情况。我有一个受基本身份验证保护的资源,可以通过浏览器,邮递员和curl轻松查询。但是在Java中,我无法查询它并得到403禁止错误。我遵循以下示例:

CredentialsProvider provider = new BasicCredentialsProvider();
UsernamePasswordCredentials credentials = new UsernamePasswordCredentials("username", "password");
provider.setCredentials(AuthScope.ANY, credentials);
CloseableHttpClient client = HttpClientBuilder.create().setDefaultCredentialsProvider(provider).build();

HttpResponse response = client.execute(new HttpGet("https://hostname.com/api/detail?query=xx"));
int statusCode = response.getStatusLine().getStatusCode();
System.out.println(statusCode);     // prints 403 forbidden

当我在调试器中检查对象时,我注意到HttpGet对象的标头为空。也就是说,它没有使用“ Basic asdflkhjWskjhakljhasdfkasdflkjh =“值传递“ Authorization”标头。

所以我手动添加了具有正确值的标头,并且标头正常工作(状态200正常)。

有人可以帮我弄清楚为什么会这样吗,我该如何使用HttpClient API设置正确的标头,而不是手动添加标头?

这是我的依赖项

<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.3</version>

1 个答案:

答案 0 :(得分:0)

这是在VM中使用以下参数运行代码所生成的调试日志:

-Dorg.apache.commons.logging.Log=org.apache.commons.logging.impl.SimpleLog
-Dorg.apache.commons.logging.simplelog.showdatetime=true
-Dorg.apache.commons.logging.simplelog.log.org.apache.http=DEBUG
-Dorg.apache.commons.logging.simplelog.log.org.apache.http.wire=ERROR

日志:

RequestAddCookies - CookieSpec selected: default
RequestAuthCache - Auth cache not set in the context
PoolingHttpClientConnectionManager - Connection request: [route: {}->http://localhost:80][total kept alive: 0; route allocated: 0 of 2; total allocated: 0 of 20]
PoolingHttpClientConnectionManager - Connection leased: [id: 0][route: {}->http://localhost:80][total kept alive: 0; route allocated: 1 of 2; total allocated: 1 of 20]
MainClientExec - Opening connection {}->http://localhost:80
DefaultHttpClientConnectionOperator - Connecting to localhost/127.0.0.1:80
DefaultHttpClientConnectionOperator - Connection established 127.0.0.1:37638<->127.0.0.1:80
MainClientExec - Executing request GET /test/ HTTP/1.1
MainClientExec - Target auth state: UNCHALLENGED
MainClientExec - Proxy auth state: UNCHALLENGED
headers - http-outgoing-0 >> GET /test/ HTTP/1.1
headers - http-outgoing-0 >> Host: localhost
headers - http-outgoing-0 >> Connection: Keep-Alive
headers - http-outgoing-0 >> User-Agent: Apache-HttpClient/4.5.3 (Java/1.8.0_131)
headers - http-outgoing-0 >> Accept-Encoding: gzip,deflate
headers - http-outgoing-0 << HTTP/1.1 401 Unauthorized
headers - http-outgoing-0 << Date: Mon, 10 Dec 2018 15:27:14 GMT
headers - http-outgoing-0 << Server: Apache/2.4.25 (Debian)
headers - http-outgoing-0 << WWW-Authenticate: Basic realm="Restricted Content"
headers - http-outgoing-0 << Content-Length: 456
headers - http-outgoing-0 << Keep-Alive: timeout=5, max=100
headers - http-outgoing-0 << Connection: Keep-Alive
headers - http-outgoing-0 << Content-Type: text/html; charset=iso-8859-1
MainClientExec - Connection can be kept alive for 5000 MILLISECONDS
HttpAuthenticator - Authentication required
HttpAuthenticator - localhost:80 requested authentication
TargetAuthenticationStrategy - Authentication schemes in the order of preference: [Negotiate, Kerberos, NTLM, Digest, Basic]
TargetAuthenticationStrategy - Challenge for Negotiate authentication scheme not available
TargetAuthenticationStrategy - Challenge for Kerberos authentication scheme not available
TargetAuthenticationStrategy - Challenge for NTLM authentication scheme not available
TargetAuthenticationStrategy - Challenge for Digest authentication scheme not available
HttpAuthenticator - Selected authentication options: [BASIC [complete=true]]
MainClientExec - Executing request GET /test/ HTTP/1.1
MainClientExec - Target auth state: CHALLENGED
HttpAuthenticator - Generating response to an authentication challenge using basic scheme
MainClientExec - Proxy auth state: UNCHALLENGED
headers - http-outgoing-0 >> GET /test/ HTTP/1.1
headers - http-outgoing-0 >> Host: localhost
headers - http-outgoing-0 >> Connection: Keep-Alive
headers - http-outgoing-0 >> User-Agent: Apache-HttpClient/4.5.3 (Java/1.8.0_131)
headers - http-outgoing-0 >> Accept-Encoding: gzip,deflate
headers - http-outgoing-0 >> Authorization: Basic *snip*
headers - http-outgoing-0 << HTTP/1.1 200 OK
headers - http-outgoing-0 << Date: Mon, 10 Dec 2018 15:27:14 GMT
headers - http-outgoing-0 << Server: Apache/2.4.25 (Debian)
headers - http-outgoing-0 << Vary: Accept-Encoding
headers - http-outgoing-0 << Content-Encoding: gzip
headers - http-outgoing-0 << Content-Length: 397
headers - http-outgoing-0 << Keep-Alive: timeout=5, max=99
headers - http-outgoing-0 << Connection: Keep-Alive
headers - http-outgoing-0 << Content-Type: text/html;charset=UTF-8
MainClientExec - Connection can be kept alive for 5000 MILLISECONDS
HttpAuthenticator - Authentication succeeded
TargetAuthenticationStrategy - Caching 'basic' auth scheme for http://localhost:80

我想指出一个事实,即客户端两次提出了请求;一次是401 Unauthorized失败而丢失了Authorization: Basic头,而第二次是在客户端意识到需要授权时带有必需的头。如果您是根据初始请求来判断调试器的,那么您可能判断得太快了。