HTTPClient 4.x 未在上下文中设置身份验证缓存
HTTPClient 4.x Auth cache not set in the context
我正在使用 HttpClient 4.5.x 调用带有 NTLM 身份验证的 SOAP Web 服务。
身份验证成功。这是一个 3 次握手。
例如,如果我做 post-request 包括图像或其他数据内容,那么对于每个握手请求,都会发送数据。
来自 HttpClients material 在线的一个建议是首先执行低请求,然后对后续的大请求使用相同的客户端上下文对象。
它还在文档中说明了这一点 - 从 4.1 版开始,HttpClient 会自动缓存有关已成功验证的主机的信息。
我也试过了。我随后在同一个方法和同一个线程中发生了这两个请求。 (默认)缓存不会发生。两次都发生了 3 次握手。
在日志中我看到以下语句
[org.apache.http.client.protocol.RequestAuthCache] Auth cache not set in the context
可能是这个默认值不适用于 NTLM。
是否有任何标志可以打开缓存?
或者我应该自己创建 AuthCache 并维护?看起来只针对抢先身份验证,创建身份验证缓存。所以,我怀疑它是否适用于我的情况。
private void callServiceWithAuthentication (ByteArrayEntity entity)
{
try {
/*
AuthScope authScope = new AuthScope("WEBSERVICE-HOST", 443, AuthScope.ANY_REALM, "ntlm");
*/
CloseableHttpClient httpclient = HttpClients.createDefault();
NTCredentials ntCredentials = new NTCredentials(this.userName, this.password, null, "DOMAIN");
CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(AuthScope.ANY, ntCredentials);
httpClientContext = HttpClientContext.create();
httpClientContext.setCredentialsProvider(credentialsProvider);
HttpHost targetHost = new HttpHost ("WEBSERVICE_HOST", 443);
// First cheap-cost request
HttpGet httpGet = new HttpGet ("WEBSERVICE_URL");
CloseableHttpResponse httpResponse = httpclient.execute(httpGet, httpClientContext);
HttpEntity getResponseEntity = httpResponse.getEntity();
// Following real costly post request
HttpPost post = new HttpPost("WEBSERVICE_URL");
post.setEntity(entity);
// Execute request
try {
CloseableHttpResponse response = httpclient.execute(post, httpClientContext);
StatusLine statusLine = response.getStatusLine();
HttpEntity rentity = response.getEntity();
System.out.println ("HTTP Response Code: " + statusLine.getStatusCode());
if (statusLine.getStatusCode() >= 300) {
throw new HttpResponseException(
statusLine.getStatusCode(),
statusLine.getReasonPhrase());
}
if (entity == null) {
throw new ClientProtocolException("Response contains no content");
}
System.out.println (rentity.getContent());
}
catch (Exception e) {
e.printStackTrace();
}
finally {
// Release current connection to the connection pool once you are done
post.releaseConnection();
}
}
catch (Exception e) {e.printStackTrace();}
finally {
}
}
我必须让第一个响应实体在第二个请求之前消费。然后第二个请求没有再次进行(3次握手)认证。
EntityUtils.consume(getResponseEntity);
我还有更多清理工作要做
我正在使用 HttpClient 4.5.x 调用带有 NTLM 身份验证的 SOAP Web 服务。 身份验证成功。这是一个 3 次握手。 例如,如果我做 post-request 包括图像或其他数据内容,那么对于每个握手请求,都会发送数据。
来自 HttpClients material 在线的一个建议是首先执行低请求,然后对后续的大请求使用相同的客户端上下文对象。 它还在文档中说明了这一点 - 从 4.1 版开始,HttpClient 会自动缓存有关已成功验证的主机的信息。
我也试过了。我随后在同一个方法和同一个线程中发生了这两个请求。 (默认)缓存不会发生。两次都发生了 3 次握手。
在日志中我看到以下语句
[org.apache.http.client.protocol.RequestAuthCache] Auth cache not set in the context
可能是这个默认值不适用于 NTLM。 是否有任何标志可以打开缓存? 或者我应该自己创建 AuthCache 并维护?看起来只针对抢先身份验证,创建身份验证缓存。所以,我怀疑它是否适用于我的情况。
private void callServiceWithAuthentication (ByteArrayEntity entity)
{
try {
/*
AuthScope authScope = new AuthScope("WEBSERVICE-HOST", 443, AuthScope.ANY_REALM, "ntlm");
*/
CloseableHttpClient httpclient = HttpClients.createDefault();
NTCredentials ntCredentials = new NTCredentials(this.userName, this.password, null, "DOMAIN");
CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(AuthScope.ANY, ntCredentials);
httpClientContext = HttpClientContext.create();
httpClientContext.setCredentialsProvider(credentialsProvider);
HttpHost targetHost = new HttpHost ("WEBSERVICE_HOST", 443);
// First cheap-cost request
HttpGet httpGet = new HttpGet ("WEBSERVICE_URL");
CloseableHttpResponse httpResponse = httpclient.execute(httpGet, httpClientContext);
HttpEntity getResponseEntity = httpResponse.getEntity();
// Following real costly post request
HttpPost post = new HttpPost("WEBSERVICE_URL");
post.setEntity(entity);
// Execute request
try {
CloseableHttpResponse response = httpclient.execute(post, httpClientContext);
StatusLine statusLine = response.getStatusLine();
HttpEntity rentity = response.getEntity();
System.out.println ("HTTP Response Code: " + statusLine.getStatusCode());
if (statusLine.getStatusCode() >= 300) {
throw new HttpResponseException(
statusLine.getStatusCode(),
statusLine.getReasonPhrase());
}
if (entity == null) {
throw new ClientProtocolException("Response contains no content");
}
System.out.println (rentity.getContent());
}
catch (Exception e) {
e.printStackTrace();
}
finally {
// Release current connection to the connection pool once you are done
post.releaseConnection();
}
}
catch (Exception e) {e.printStackTrace();}
finally {
}
}
我必须让第一个响应实体在第二个请求之前消费。然后第二个请求没有再次进行(3次握手)认证。
EntityUtils.consume(getResponseEntity);
我还有更多清理工作要做