首页 文章

Apache HttpClient 4.4 Proxy Basic Auth:多次auth尝试

提问于
浏览
3

我正在尝试通过带有Basic Auth的代理向HTTP Client 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请求一个没有信用,一个有信用,两个都返回407,看起来合乎逻辑):

2015/10/07 13:39:02:502 CEST [WARN] BasicAuthCache - 序列化auth方案时出现意外的I / O错误java.io.NotSerializableException:test.Main at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java: 1183)在java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1547)java. java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1508)java. java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1431) . io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1177),位于org.apache.http.impl.client.BasicAuthCache.put(BasicAuthCache.java:107)的java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:347) test.Main.send上的.Main.proxyAuthenticate(Main.java:109)(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: - > http://proxy.the -proxy.xyz:1234->https://the-backend.xyz:443] [保持活着:0;分配路由:0 of 3;总分配:0 of 3] 2015/10/07 13:39:02:502 CEST [DEBUG] PoolingHttpClientConnectionManager - 连接租用:[id:1] [route: - > http://proxy.the-proxy .xyz:1234-> https://the-backend.xyz:443] [总保持活力:0;分配的路线:1个中的1个;总分配:1/3] 2015/10/07 13:39:02:502 CEST [DEBUG] MainClientExec - 打开连接 - > http://proxy.the-proxy.xyz:1234-> 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 - Build 连接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 [DEBUG] headers - 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代理身份验证需要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 [DEBU G] headers - http-outgoing-1 << Cache-Control:no-cache 2015/10/07 13:39:07:530 CEST [DEBUG] headers - 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] header - http-outgoing-1 << Proxy-Connection:close 2015/10/07 13:39:07:530 CEST [DEBUG ] headers - http-outgoing-1 <<连接: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 [DEBUG] HttpAuthenticator - proxy.the-proxy.xyz:1234请求身份验证2015/10/07 13:39 :07:530 CEST [DEBUG] ProxyAuthenticationStrategy - 优先顺序的认证方案:[Negotiate,Kerberos,NTLM,Digest,Basic] 2015/10/07 13:39:07:530 CEST [DEBUG] ProxyAuthenticationStrategy - Negotiate的挑战认证方案不可用2015/10/07 13:39:07:530 CEST [DEBUG] ProxyAuthenticationStrategy - Kerberos认证方案的挑战不可用2015/10/07 13:39:07:530 CEST [DEBUG] ProxyAuthenticationStrategy - NTLM的挑战认证方案不可用2 015/10/07 13:39:07:530 CEST [DEBUG] ProxyAuthenticationStrategy - 摘要认证方案的挑战不可用2015/10/07 13:39:07:530 CEST [DEBUG] HttpAuthenticator - 选择的认证选项:[BASIC [完成=真]] 2015/10/07 13:39:07:530 CEST [DEBUG] DefaultManagedHttpClientConnection - http-outgoing-1:关闭连接2015/10/07 13:39:07:530 CEST [DEBUG] DefaultHttpClientConnectionOperator - 连接to proxy.the-proxy.xyz/123.45.67.890:1234 2015/10/07 13:39:12:560 CEST [DEBUG] DefaultHttpClientConnectionOperator - Build 连接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 >> CONNECT-backend.xyz:443 HTTP / 1.1 2015/10/07 13:39:12:560 CEST [DEBUG] Headers - http-outgoing-1 >>主持人:the-backend.xyz 2015/10/07 13:39:12:560 CEST [DEBUG] Headers - http-outgoing-1 >> User-Agent:Apache-HttpClient / 4.4.1(Java / 1.7.0_51)2015/10/07 13:39:12:560 CEST [DEBUG] headers - http-outgoing-1 >>代理授权:基本xXXxxXxXXXXX 2015/10/07 13:39:12:561 CEST [DEBUG]标头 - http-outgoing-1 << HTTP / 1.1 407需要代理验证2015/10/07 13:39:12:561 CEST [DEBUG]标头 - http-outgoing-1 <<代理 - 认证:BASIC领域=“InternetAccess”2015/10/07 13:39:12:561 CEST [DEBUG]标头 - http-outgoing-1 << Cache-控制: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 ] headers - http-outgoing-1 << Content-Type:text / html; charset = utf-8 2015/10/07 13:39:12:561 CEST [DEBUG] header - http-outgoing-1 << Proxy-Connection:close 2015/10/07 13:39:12:561 CEST [DEBUG ] header - http-outgoing-1 <<连接:关闭2015/10/07 13:39:12:561 CEST [DEBUG] header - http-outgoing-1 << Content-Length: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] [route: - > http://proxy.the-proxy.xyz:1234-> https://the-backend.xyz:443] [总保持活力:0;分配路由:0 of 3;总分配:0 of 3] ################### 407

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

2015/10/07 13:39:17:585 CEST [WARN] BasicAuthCache - 序列化auth方案时出现意外的I / O错误java.io.NotSerializableException:test.Main at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java: 1183)在java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1547)java. java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1508)java. java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1431) . io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1177),位于org.apache.http.impl.client.BasicAuthCache.put(BasicAuthCache.java:107)的java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:347) test.Main.send(Main.java:56)at test.Main2.main(Main2.java:32)2015.Mac/10:17 [DEBUG] RequestAddCookies - 选择CookieSpec:默认2015/10/07 13:39:17:585 CEST [DEBUG] PoolingHttpClientConnectionManager - 连接请求:[route: - > http://proxy.the -proxy.xyz:1234->https://the-backend.xyz:443] [保持活着:0;分配路由:0 of 3;总分配:0 of 3] 2015/10/07 13:39:17:585 CEST [DEBUG] PoolingHttpClientConnectionManager - 连接租用:[id:2] [route: - > http://proxy.the-proxy .xyz:1234-> https://the-backend.xyz:443] [总保持活力:0;分配的路线:1个中的1个;总分配:1/3] 2015/10/07 13:39:17:585 CEST [DEBUG] MainClientExec - 打开连接 - > http://proxy.the-proxy.xyz:1234-> 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 - Build 连接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 [DEBUG] Headers - http-outgoing-2 >> User-Agent:Apache-HttpClient / 4.4.1(Java / 1.7.0_51)2015/10/07 13:39:17:586 CEST [DEBUG ] headers - http-outgoing-2 << HTTP / 1.1 407需要代理身份验证2015/10/07 13:39:17:586 CEST [DEBUG] headers - http-outgoing-2 << Proxy-Authenticate:BASICrealm =“InternetAccess”2015/10/07 13:39:17:586 CEST [DEBUG] Headers - http-outgoing-2 << Cache-Control:no-cache 2015/10/07 13:39:17:586 CEST [DEBUG] Headers - 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] header - http-outgoing-2 << Proxy-Connection:close 2015/10/07 13:39:17:586 CEST [DEBUG ] header - http-outgoing-2 <<连接:关闭2015/10/07 13:39:17:586 CEST [DEBUG] Headers - http-outgoing-2 <<内容 - 长度: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:3 9:17:586 CEST [DEBUG] PoolingHttpClientConnectionManager - 已发布连接:[id:2] [route: - > http://proxy.the-proxy.xyz:1234-> https:// the-backend . xyz:443] [保持活力:0;分配路由:0 of 3;总分配:0 of 3] ################### 407

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

谢谢 !

UPDATE:

If I change the HttpClient (from 4.4) to DefaultHttpClient (from 4.3) and adapt these two methods, it works. Note that the getCredentialsProvider is called from the client in 4.3 and from context in 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

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

    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
    

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

相关问题