Apache HttpClient 4.4 Proxy Basic Auth:多次授权尝试

时间:2015-10-07 11:57:59

标签: java apache-httpclient-4.x

我尝试通过带有Basic Auth的代理向HTTP Client 4.4发送请求。 如果我输入正确的凭据,则连接成功。

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

似乎一旦我们第一次提供(错误的)凭据,就不会发送新的(正确或错误的)凭据。

您会看到有两个电话:

  1. 第一次通话,错误的代理凭证
  2. 第二次通话,正确的代理凭证
  3. 代码:

    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请求一个没有信用,一个有信用,两个都返回407,看起来合乎逻辑):

      

    2015/10/07 13:39:02:502 CEST [WARN] BasicAuthCache - 意外的I / O   序列化auth方案时出错java.io.NotSerializableException:test.Main at   java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1183)     在   java.io.ObjectOutputStream.defaultWriteFields(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.proxyAuthenticate(Main.java:109)at   test.Main.send(Main.java:56)在test.Main2.main(Main2.java:30)

         

    2015/10/07 13:39:02:502 CEST [DEBUG] RequestAddCookies - CookieSpec   已选择:默认2015/10/07 13:39:02:502 CEST [DEBUG]   PoolingHttpClientConnectionManager - 连接请求:[route:   {TLS} - GT; http://proxy.the-proxy.xyz:1234-&GT; https://the-backend.xyz:443][total   活着:0;分配路由:0 of 3;总分配:0 of 3]   2015/10/07 13:39:02:502 CEST [DEBUG]   PoolingHttpClientConnectionManager - 连接租用:[id:1] [route:   {TLS} - GT; http://proxy.the-proxy.xyz:1234-&GT; https://the-backend.xyz:443][total   活着:0;分配的路线:1个中的1个;总分配:1 of 3]   2015/10/07 13:39:02:502 CEST [DEBUG] MainClientExec - 开放   连接   {TLS} - GT; http://proxy.the-proxy.xyz:1234-&GT; https://the-backend.xyz:443   2015/10/07 13:39:02:502 CEST [DEBUG]   DefaultHttpClientConnectionOperator - 连接到   proxy.the-proxy.xyz/123.45.67.890:1234 2015/10/07 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]标题 - http-outgoing-1&gt;&gt; CONNECT   the-backend.xyz:443 HTTP / 1.1 2015/10/07 13:39:07:530   CEST [DEBUG]标题 - http-outgoing-1&gt;&gt;主办:   the -backend.xyz 2015/10/07 13:39:07:530 CEST [DEBUG]   标题 - http-outgoing-1&gt;&gt; User-Agent:Apache-HttpClient / 4.4.1   (Java / 1.7.0_51)2015/10/07 13:39:07:530 CEST [DEBUG]标题 -   http-outgoing-1&lt;&lt;需要HTTP / 1.1 407代理验证   2015/10/07 13:39:07:530 CEST [DEBUG]标题 - http-outgoing-1&lt;&lt;   代理验证:BASIC领域=&#34; InternetAccess&#34; 2015年10月7日   13:39:07:530 CEST [DEBUG]标题 - http-outgoing-1&lt;&lt;缓存控制:   no-cache 2015/10/07 13:39:07:530 CEST [DEBUG]标题 -   http-outgoing-1&lt;&lt; Pragma:no-cache 2015/10/07 13:39:07:530 CEST   [DEBUG]标题 - http-outgoing-1&lt;&lt;内容类型:text / html;   charset = utf-8 2015/10/07 13:39:07:530 CEST [DEBUG]标题 -   http-outgoing-1&lt;&lt;代理连接:关闭2015/10/07 13:39:07:530   CEST [DEBUG]标题 - http-outgoing-1&lt;&lt;连线:关闭2015/10/07   13:39:07:530 CEST [DEBUG]标题 - http-outgoing-1&lt;&lt;内容长度:   2916 2015/10/07 13:39:07:530 CEST [DEBUG] HttpAuthenticator -   需要认证2015/10/07 13:39:07:530 CEST [DEBUG]   HttpAuthenticator - proxy.the-proxy.xyz:1234请求身份验证   2015/10/07 13:39:07:530 CEST [DEBUG] ProxyAuthenticationStrategy -   优先顺序的认证方案:[谈判,   Kerberos,NTLM,Digest,Basic] 2015/10/07 13:39:07:530 CEST [DEBUG]   ProxyAuthenticationStrategy - 协商认证的挑战   计划不可用2015/10/07 13:39:07:530 CEST [DEBUG]   ProxyAuthenticationStrategy - Kerberos身份验证的挑战   计划不可用2015/10/07 13:39:07:530 CEST [DEBUG]   ProxyAuthenticationStrategy - NTLM身份验证方案的挑战   不可用2015/10/07 13:39:07:530 CEST [DEBUG]   ProxyAuthenticationStrategy - 摘要式身份验证的挑战   计划不可用2015/10/07 13:39:07:530 CEST [DEBUG]   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/07 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 [DEBUG]   标题 - http-outgoing-1&gt;&gt; CONNECT   the-backend.xyz:443 HTTP / 1.1 2015/10/07 13:39:12:560   CEST [DEBUG]标题 - http-outgoing-1&gt;&gt;主办:   the -backend.xyz 2015/10/07 13:39:12:560 CEST [DEBUG]   标题 - http-outgoing-1&gt;&gt; User-Agent:Apache-HttpClient / 4.4.1   (Java / 1.7.0_51)2015/10/07 13:39:12:560 CEST [DEBUG]标题 -   http-outgoing-1&gt;&gt;代理授权:基本xXXxxXxXXXXX 2015/10/07   13:39:12:561 CEST [DEBUG]标题 - http-outgoing-1&lt;&lt; HTTP / 1.1 407   需要代理身份验证2015/10/07 13:39:12:561 CEST [DEBUG]   headers - http-outgoing-1&lt;&lt;代理验证:BASIC   境界=&#34;及网络连接。&#34; 2015/10/07 13:39:12:561 CEST [DEBUG]标题 -   http-outgoing-1&lt;&lt; Cache-Control:no-cache 2015/10/07 13:39:12:561   CEST [DEBUG]标题 - http-outgoing-1&lt;&lt; Pragma:no-cache 2015/10/07   13:39:12:561 CEST [DEBUG]标题 - http-outgoing-1&lt;&lt;内容类型:   为text / html; charset = utf-8 2015/10/07 13:39:12:561 CEST [DEBUG]标题    - http-outgoing-1&lt;&lt;代理连接:关闭2015/10/07 13:39:12:561 CEST [DEBUG]标题 - http-outgoing-1&lt;&lt;连线:关闭2015/10/07   13:39:12:561 CEST [DEBUG]标题 - http-outgoing-1&lt;&lt;内容长度:   2966 2015/10/07 13:39:12:561 CEST [DEBUG] HttpAuthenticator -   需要认证2015/10/07 13:39:12:561 CEST [DEBUG]   HttpAuthenticator - proxy.the-proxy.xyz:1234请求身份验证   2015/10/07 13:39:12:561 CEST [DEBUG] HttpAuthenticator - 授权   挑战已处理2015/10/07 13:39:12:561 CEST [DEBUG]   HttpAuthenticator - 身份验证失败2015/10/07 13:39:12:561 CEST   [DEBUG] ProxyAuthenticationStrategy - 清除缓存的身份验证方案   http://proxy.the-proxy.xyz:1234 2015/10/07 13:39:12:561 CEST [DEBUG]   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 [DEBUG]   MainClientExec - 连接丢弃2015/10/07 13:39:12:561 CEST   [DEBUG] DefaultManagedHttpClientConnection - http-outgoing-1:关闭   连接2015/10/07 13:39:12:561 CEST [DEBUG]   PoolingHttpClientConnectionManager - 发布连接:[id:   1] [路线:   {TLS} - GT; http://proxy.the-proxy.xyz:1234-&GT; https://the-backend.xyz:443][total   活着:0;分配路由:0 of 3;总分配:0 of 3]

         ################### 407

    第二次尝试的日志(连接正确的代理服务器信息:只有一个http请求,为什么没有第二个具有正确信用的请求?)

      

    2015/10/07 13:39:17:585 CEST [WARN] BasicAuthCache - 意外的I / O   序列化auth方案时出错java.io.NotSerializableException:test.Main at   java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1183)     在   java.io.ObjectOutputStream.defaultWriteFields(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.proxyAuthenticate(Main.java:109)at   test.Main.send(Main.java:56)at test.Main2.main(Main2.java:32)

         

    2015/10/07 13:39:17:585 CEST [DEBUG] RequestAddCookies - CookieSpec   已选择:默认2015/10/07 13:39:17:585 CEST [DEBUG]   PoolingHttpClientConnectionManager - 连接请求:[route:   {TLS} - GT; http://proxy.the-proxy.xyz:1234-&GT; https://the-backend.xyz:443][total   活着:0;分配路由:0 of 3;总分配:0 of 3]   2015/10/07 13:39:17:585 CEST [DEBUG]   PoolingHttpClientConnectionManager - 连接租用:[id:2] [route:   {TLS} - GT; http://proxy.the-proxy.xyz:1234-&GT; https://the-backend.xyz:443][total   活着:0;分配的路线:1个中的1个;总分配:1 of 3]   2015/10/07 13:39:17:585 CEST [DEBUG] MainClientExec - 开放   连接   {TLS} - GT; http://proxy.the-proxy.xyz:1234-&GT; https://the-backend.xyz:443   2015/10/07 13:39:17:585 CEST [DEBUG]   DefaultHttpClientConnectionOperator - 连接到   proxy.the-proxy.xyz/123.45.67.890:1234   2015/10/07 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]标题 - http-outgoing-2&gt;&gt; CONNECT   the-backend.xyz:443 HTTP / 1.1 2015/10/07 13:39:17:586   CEST [DEBUG]标题 - http-outgoing-2&gt;&gt;主办:   the -backend.xyz 2015/10/07 13:39:17:586 CEST [DEBUG]   标题 - http-outgoing-2&gt;&gt; User-Agent:Apache-HttpClient / 4.4.1   (Java / 1.7.0_51)2015/10/07 13:39:17:586 CEST [DEBUG]标题 -   http-outgoing-2&lt;&lt;需要HTTP / 1.1 407代理验证   2015/10/07 13:39:17:586 CEST [DEBUG]标题 - http-outgoing-2&lt;&lt;   代理验证:BASIC领域=&#34; InternetAccess&#34; 2015年10月7日   13:39:17:586 CEST [DEBUG]标题 - http-outgoing-2&lt;&lt;缓存控制:   no-cache 2015/10/07 13:39:17:586 CEST [DEBUG]标题 -   http-outgoing-2&lt;&lt; Pragma:no-cache 2015/10/07 13:39:17:586 CEST   [DEBUG]标题 - http-outgoing-2&lt;&lt;内容类型:text / html;   charset = utf-8 2015/10/07 13:39:17:586 CEST [DEBUG]标题 -   http-outgoing-2&lt;&lt;代理连接:关闭2015/10/07 13:39:17:586   CEST [DEBUG]标题 - http-outgoing-2&lt;&lt;连线:关闭2015/10/07   13:39:17:586 CEST [DEBUG]标题 - http-outgoing-2&lt;&lt;内容长度:   2916 2015/10/07 13:39:17:586 CEST [DEBUG] HttpAuthenticator -   需要认证2015/10/07 13:39:17:586 CEST [DEBUG]   HttpAuthenticator - proxy.the-proxy.xyz:1234请求身份验证   2015/10/07 13:39:17:586 CEST [DEBUG]   DefaultManagedHttpClientConnection - http-outgoing-2:关闭连接   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 [DEBUG]   MainClientExec - 连接丢弃2015/10/07 13:39:17:586 CEST   [DEBUG] DefaultManagedHttpClientConnection - http-outgoing-2:关闭   连接2015/10/07 13:39:17:586 CEST [DEBUG]   PoolingHttpClientConnectionManager - 发布连接:[id:   2] [路线:   {TLS} - GT; http://proxy.the-proxy.xyz:1234-&GT; https://the-backend.xyz:443][total   活着:0;分配路由:0 of 3;总分配:0 of 3]

         ################### 407

    任何想法为什么在第二次尝试时,它尝试没有auth(正常),服务器回复需要Basic auth,然后它不会尝试使用正确的凭据,而是关闭连接。

    谢谢!

    更新

    如果我将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 !!!!!!!!!!!!!!!!!
    }
    

1 个答案:

答案 0 :(得分: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

由于序列化也可能存在异常。