我试图通过具有基本身份验证的代理通过HTTP客户端4.4发送请求。 如果我输入正确的凭证,则连接成功。Apache HttpClient 4.4代理基本身份验证:多次验证尝试
但是,如果我输入了错误的凭据,则即使使用正确的凭据,以下所有其他连接尝试都将失败。
似乎只要我们第一次提供了(错误的)凭证,新的(正确或错误的)凭证就不会被发送。
你会看到有两个电话:
- 第一个呼叫,错误的代理证书
- 第二个呼叫,正确的代理证书
代码:
package test;
import org.apache.commons.codec.binary.Base64;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
public class Main {
private HttpClient client;
private HttpClientContext context = HttpClientContext.create();
public static void main(String[] args) throws Exception {
System.setProperty("org.apache.commons.logging.Log", "org.apache.commons.logging.impl.SimpleLog");
System.setProperty("org.apache.commons.logging.simplelog.showdatetime", "true");
System.setProperty("org.apache.commons.logging.simplelog.log.org.apache.http", "DEBUG");
System.setProperty("org.apache.commons.logging.simplelog.log.org.apache.http.wire", "ERROR");
Main main = new Main();
main.createHttpClient();
main.send(true, "test", "wrong"); // 1st call, wrong credentials, if this call is removed, it works !
main.send(true, "test", "correct"); // 2nd call, correct credentials
}
public void send(String username, String password) throws Exception {
proxyAuthenticate(username, password);
HttpUriRequest request = new HttpGet("https://the-backend.xyz");
HttpResponse httpResponse = client.execute(request, context);
int statusCode = httpResponse.getStatusLine().getStatusCode();
System.out.println("######################### " + statusCode);
}
public void createHttpClient() throws Exception {
HttpClientBuilder httpClientBuilder = HttpClients.custom();
httpClientBuilder.setProxy(new HttpHost("proxy.the-proxy.xyz", 1234));
client = httpClientBuilder.build();
}
private void proxyAuthenticate(String username, String password) {
UsernamePasswordCredentials credentials = new UsernamePasswordCredentials(username, password);
AuthScope scope = new AuthScope("proxy.the-proxy.xyz", 1234);
CredentialsProvider provider = new BasicCredentialsProvider();
provider.setCredentials(scope, credentials);
context.setCredentialsProvider(provider);
}
}
的记录第一次尝试(连接错误的代理信誉:两个http请求一个没有信用,一个用vim的信任状,既返回407,看起来逻辑):
2015年10月7日13:39:02:502 CEST [WARN] BasicAuthCache - 意外的I/O错误 在序列AUTH方案java.io.NotSerializableException :test.Main在 java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1183) 在 java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1547) 在 java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream中。 java:1508) at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1431) at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1177) 在 java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:347) 在 org.apache.http.impl.client.BasicAuthCache.put(BasicAuthCache的.java:107) 在test.Main.proxyAuthenticate(Main.java:109)在 test.Main.send(Main.java:56)在test.Main2.main(Main2.java:30)
2015/10/07 13:39:02:502 CEST [DEBUG] RequestAddCookies - CookieSpec selected:default 2015/10/07 13:39:02:502 CEST [调试] PoolingHttpClientConnectionManager - 连接请求:[路由: { tls} - >http://proxy.the-proxy.xyz:1234->https://the-backend.xyz:443][total 保持活着:0;分配的路由:3个中的0个;总分配:2015年10月7日13 0 3] :39:02:502 CEST [DEBUG] PoolingHttpClientConnectionManager - 连接租用:[ID:1] [路线: {TLS} - >http://proxy.the-proxy.xyz:1234->https://the-backend.xyz:443][total 保持活:0;分配的路由:3个中的1个;总分配:2015年10月7日13 1 3] :39:02:502 CEST [DEBUG] MainClientExec - 打开 连接 {TLS} - >http://proxy.the-proxy.xyz:1234->https://the-backend.xyz:443 2015年10月7日13时39分02秒: 502 CEST [DEBUG] DefaultHttpClientConnectionOperator - 连接到 proxy.the-proxy.xyz/123.45.67.890:1234 2015年10月7日13:39:07:530 CEST [DEBUG] DefaultHttpClientConnectionOperator - 连接建立 321.54.76.098: 58216 < - > 123.45.67。890:1234 2015/10/07 13:39:07:530 CEST [DEBUG] headers - http-outgoing-1 >> CONNECT the-backend.xyz:443 HTTP/1.1 2015/10/07 13:39:07 :530 CEST [DEBUG] headers - http-outgoing-1 >>主机: the-backend.xyz 2015/10/07 13:39:07:530 CEST [调试] 头文件 - http-outgoing-1 >> User-Agent:Apache-HttpClient/4.4.1 (Java/1.7.0_51)2015/10/07 13:39:07:530 CEST [DEBUG] headers - http-outgoing-1 < < HTTP/1.1 407 Proxy需要身份验证 2015/10/07 13:39:07:530 CEST [DEBUG] headers - http-outgoing-1 < < Proxy-Authenticate:BASIC realm =“InternetAccess”2015/10/07 13:39:07 :530 CEST [DEBUG]头文件 - http-outgoing-1 < < Cache-Control: no-cache 2015/10/07 13:39:07:530 CEST [DEBUG]头文件 - http-outgoing-1 < < Pragma:no-cache 2015/10/07 13:39: 07:530 CEST [DEBUG] headers - http-outgoing-1 < < Content-Type:text/html; charset = utf-8 2015/10/07 13:39:07:530 CEST [DEBUG]头文件 - http-outgoing-1 < <代理连接:关闭2015/10/07 13:39:07:530 CEST [DEBUG] headers -http-outgoing-1 < < Connection:close 2015/10/07 13:39:07:530 CEST [DEBUG] headers - http-outgoing-1 < < Content-Length: 2916 2015/10/07 13:39:07:530 CEST [DEBUG] HttpAuthenticator - 需要身份验证2015/10/07 13:39:07:530 CEST [调试] HttpAuthenticator - proxy.the-proxy.xyz:1234请求身份验证 2015/10/07 13:39:07:530 CEST [DEBUG] ProxyAuthenticationStrategy - 订单中的验证方案[谈判, Kerberos,NTLM,摘要,基本] 2015/10/07 13:39:07:530 CEST [调试] ProxyAuthenticationStrategy - 协商身份验证的挑战 方案不可用2015/10/07 13:39 :07:530 CEST [调试] ProxyAuthenticationStrategy - 对Kerberos身份验证的挑战 方案不可用2015/10/07 13:39:07:530 CEST [调试] ProxyAuthenticationStrategy - NTLM身份验证方案的挑战 不可用2015/10/07 13:39:07:530 CEST [调试] ProxyAuthenticationStrategy - 对摘要式身份验证的挑战 计划不可用2015/10/07 13:39:07:530 CEST [调试] HttpAuthenticator - 选择的身份验证选项:[BASIC [complete = true]] 2015/10/07 13:39:07:530 CEST [DEBUG] DefaultManagedHttpClientConnection - http-outgoing-1:关闭连接 2015/10/07 13:39:07:530 CEST [DEBUG ] DefaultHttpClientConnectionOperator - 连接到 proxy.the-proxy.xyz/123.45.67.890:1234 2015年10月7日13:39:12:560 CEST [DEBUG] DefaultHttpClientConnectionOperator - 连接建立 321.54.76.098:58217 < - > 123.45.67.890:1234 2015/10/07 13:39:12:560 CEST [DEBUG] HttpAuthenticator - 生成对身份验证的响应 使用基本方案的挑战2015/10/07 13:39:12:560 CEST [调试] 头文件 - http-outgoing-1 >> CONNECT the-backend.xyz:443 HTTP/1.1 2015/10/07 13:39:12:560 C EST [DEBUG]标头 - http-outgoing-1 >>主机: the-backend.xyz 2015/10/07 13:39:12:560 CEST [调试] 标头 - http-outgoing-1 >>用户代理:Apache-HttpClient/4.4.1 (Java/1.7。0_51)2015/10/07 13:39:12:560 CEST [DEBUG] headers - http-outgoing-1 >> Proxy-Authorization:Basic xXXxxXxXXXXX 2015/10/07 13:39:12:561 CEST [DEBUG ]报头 - HTTP出射-1 < < HTTP/1.1 407 代理身份验证2015年10月7日13:39:12:561 CEST [DEBUG] 头 - HTTP出射-1 < <代理验证:BASIC realm =“InternetAccess”2015/10/07 13:39:12:561 CEST [DEBUG] headers - http-outgoing-1 < < Cache-Control:no-cache 2015/10/07 13:39:12:561 CEST [DEBUG] headers - http-outgoing-1 < < Pragma:no-cache 2015/10/07 13:39:12:561 CEST [DEBUG] he aders - http-outgoing-1 < < Content-Type: text/html; charset = utf-8 2015/10/07 13:39:12:561 CEST [DEBUG]头文件 - http-outgoing-1 < <代理连接:关闭2015/10/07 13:39:12:561 CEST [ DEBUG]头文件 - http-outgoing-1 < < <连接:close 2015/10/07 13:39:12:561 CEST [DEBUG] headers - http-outgoing-1 < < Content-Length: 2966 2015/10/07 13:39:12:561 CEST [DEBUG] HttpAuthenticator - 需要身份验证2015/10/07 13:39:12:561 CEST [调试] HttpAuthenticator - proxy.the-proxy.xyz:1234请求身份验证 2015/10/07 13:39:12:561 CEST [DEBUG] HttpAuthenticator - 授权 处理的挑战2015/10/07 13:39:12:561 CEST [调试] HttpAu验证失败2015/10/07 13:39:12:561 CEST [DEBUG] ProxyAuthenticationStrategy - 清除缓存的认证方案 http://proxy.the-proxy.xyz:1234 2015/10/07 13:39:12:561 CEST [调试] DefaultManagedHttpClientConnection - http -outgoing-1:关闭连接 2015/10/07 13:39:12:561 CEST [DEBUG] MainClientExec - CONNECT拒绝 代理服务器:HTTP/1.1 407代理服务器验证必需2015/10/07 13:39:12 :561 CEST [DEBUG] DefaultManagedHttpClientConnection - http-outgoing-1:关闭连接2015/10/07 13:39:12:561 CEST [调试] MainClientExec - 连接丢弃2015/10/07 13:39:12:561 CEST [DEBUG] DefaultManagedHttpClientConnection - http-outgoing-1:关闭 连接2015年10月7日13:39:12:561 CEST [DEBUG] PoolingHttpClientConnectionManager - 释放连接:[ID: 1] [路线: {TLS} - >http://proxy.the-proxy.xyz:1234->https://the-backend.xyz:443][total 保持存活:0;分配的路由:3个中的0个;总分配:0的3]
################### 407
为第二尝试的日志(连接与正确的代理名气:只有一个HTTP请求,为什么没有与正确的creds ???)的第二请求:
2015年10月7日13:39:17:585 CEST [WARN] BasicAuthCache - 意外的I/O 而错误序列化认证方案java.io.NotSerializableException:test.Main at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1183) at java.io.ObjectOutputStream.d efaultWriteFields(ObjectOutputStream.java:1547) 在 java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1508) 在 java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1431) 在 java.io.ObjectOutputStream中.writeObject0(ObjectOutputStream中。的java:1177) 在 java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:347) 在 org.apache.http.impl.client.BasicAuthCache.put(BasicAuthCache.java:107) 在test.Main。代理验证(Main.java:109) test.Main.send(Main.java:56)at test.Main2.main(Main2.java:32)
2015/10/07 13:39:17: 585 CEST [调试] RequestAddCookies - CookieSpec 选自:默认2015年10月7日13:39:17:585 CEST [DEBUG] PoolingHttpClientConnectionManager - 连接请求:[路线: {TLS} - >http://proxy.the-proxy.xyz:1234->https://the-backend.xyz:443][total 保持存活: 0;分配的路由:3个中的0个;总分配:2015年10月7日13 0 3] :39:17:585 CEST [DEBUG] PoolingHttpClientConnectionManager - 连接租用:[ID:2] [路线: {TLS} - >http://proxy.the-proxy.xyz:1234->https://the-backend.xyz:443][total 保持活:0;分配的路由:3个中的1个;总分配:2015年10月7日13 1 3] :39:17:585 CEST [DEBUG] MainClientExec - 打开 连接 {TLS} - >http://proxy.the-proxy.xyz:1234->https://the-backend.xyz:443 2015年10月7日13时39分十七秒: 585 CEST [DEBUG] DefaultHttpClientConnectionOperator - 连接到 proxy.the-proxy.xyz/123.45.67.890:1234 2015年10月7日13:39:17:585 CEST [DEBUG] DefaultHttpClientConnectionOperator - 连接建立 321.54.76.098: 58218 < - > 123.45.67.890:1234 2015/10/07 13:39:17:586 CEST [DEBUG] headers - http-outgoing-2 >> CONNECT the-backend.xyz:443 HTTP/1.1 2015/10/07 13:39:17:586 CEST [DEBUG] headers - http-outgoing-2 >>主机: the-backend.xyz 2015/10/07 13:39:17:586 CEST [调试] 头部 - http-outgoing-2 >>用户代理:Apache-HttpClient/4.4.1 (Java/1.7.0_51)2015/10/07 13:39:17:586 CEST [DEBUG]头文件 - http-outgoing-2 < < HTTP/1.1 407需要代理验证 2015/10/07 13:39:17:586 CEST [DEBUG] headers - http-outgoing -2 < < 代理验证:BASIC境界= “及网络连接。” 2015年10月7日13 :39:17:586 CEST [DEBUG]报头 - HTTP出射-2 < <缓存控制: 无缓存2015/10/07 13:39:17:586 CEST [DEBUG]头文件 - http-outgoing-2 < < Pragma:no-cache 2015/10/07 13:39:17:586 CEST [DEBUG] headers - http-outgoing-2 < < Content-Type:text/html; charset = utf-8 2015/10/07 13:39:17:586 CEST [DEBUG]头文件 - http-outgoing-2 < <代理连接:关闭2015/10/07 13:39:17:586 CEST [DEBUG] headers - http-outgoing-2 < <连接:close 2015/10/07 13:39:17:586 CEST [DEBUG] headers - http-outgoing-2 < < Content-Length: 2916 2015/10/07 13:39:17:586 CEST [DEBUG] HttpAuthenticator - 需要身份验证2015/10/07 13:39:17:586 CEST [调试] HttpAuthenticator - proxy.the-proxy.xyz:1234请求身份验证 2015/10/07 13:39:17:586 CEST [调试] DefaultManagedHttpClientConnection - http-outgoing-2:关闭连接ction 2015/10/07 13:39:17:586 CEST [DEBUG] MainClientExec - CONNECT拒绝 通过代理:HTTP/1。1 407需要代理验证2015/10/07 13:39:17:586 CEST [DEBUG] DefaultManagedHttpClientConnection - http-outgoing-2:关闭连接2015/10/07 13:39:17:586 CEST [调试] MainClientExec - 连接丢弃2015/10/07 13:39:17:586 CEST [DEBUG] DefaultManagedHttpClientConnection - http-outgoing-2:关闭 连接2015/10/07 13:39:17:586 CEST [调试] PoolingHttpClientConnectionManager - 已发布的连接:[id: 2] [route: {tls} - >http://proxy.the-proxy.xyz:1234->https://the-backend.xyz:443][total keep alive:0;分配的路由:3个中的0个;总分配:0 3]
################### 407
任何想法,为什么在第2次尝试,它试图未经身份验证(正常),服务器会回复基本身份验证是必需的,然后不是使用正确的凭据进行尝试,而是关闭连接。
谢谢!
UPDATE:
如果我改变的HttpClient(4.4),以DefaultHttpClient(4.3)和适应这两种方法,它的工作原理。 请注意,getCredentialsProvider从4.3的客户端和4.4的上下文中调用!
第一次我收到407状态码,但第二次收到200,这是我所期望的。
public void createHttpClient() throws Exception {
client = new DefaultHttpClient();
HttpHost proxy = new HttpHost("proxy.eurocontrol.be", 9513);
ConnRouteParams.setDefaultProxy(client.getParams(), proxy);
}
private void proxyAuthenticate(String username, String password) {
UsernamePasswordCredentials credentials = new UsernamePasswordCredentials(username, password);
AuthScope scope = new AuthScope("proxy.eurocontrol.be", 9513);
client.getCredentialsProvider().setCredentials(scope, credentials);
// Called from client !!!!!!!!!!!!!!!!!
}
您可以在13:39:07:530的第一个日志中看到它再次尝试,并且这次是凭证(13:39:12:560 CEST [DEBUG]标头 - http-outgoing-1代理授权:基本xXXxxXxXXXXX)。关于I/O错误,这是一个警告。 –