2015-10-07 99 views
2

我试图通过具有基本身份验证的代理通过HTTP客户端4.4发送请求。 如果我输入正确的凭证,则连接成功。Apache HttpClient 4.4代理基本身份验证:多次验证尝试

但是,如果我输入了错误的凭据,则即使使用正确的凭据,以下所有其他连接尝试都将失败。

似乎只要我们第一次提供了(错误的)凭证,新的(正确或错误的)凭证就不会被发送。

你会看到有两个电话:

  1. 第一个呼叫,错误的代理证书
  2. 第二个呼叫,正确的代理证书

代码:

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 !!!!!!!!!!!!!!!!! 
} 

回答

0

代码的第一行清楚地表明这两个请求都已完成。

First at - 2015/10/07 13:39:02:502 

Second at - 2015/10/07 13:39:17:585 

什么要打印的是服务器响应的状态代码,请参阅thisHttp Status 407

即使你的日志说清楚

Unexpected I/O error while serializing auth scheme java.io.NotSerializableException 

可以有一个例外,因为串行化也。

+0

您可以在13:39:07:530的第一个日志中看到它再次尝试,并且这次是凭证(13:39:12:560 CEST [DEBUG]标头 - http-outgoing-1代理授权:基本xXXxxXxXXXXX)。关于I/O错误,这是一个警告。 –