简体   繁体   English

Apache Http Client 4.0.1 SSL代理

[英]Apache Http Client 4.0.1 SSL Proxy

I am using Apache Http client 4.0.1 for communicating with the server. 我正在使用Apache Http客户端4.0.1与服务器进行通信。 I already have a secure/non secure client code that works just fine. 我已经有一个安全/不安全的客户端代码,可以正常工作。

Recently the new addition being to add proxy to this code, so i added the following piece of code to do that (currently non secure proxy), 最近,新增加的功能是向此代码添加代理,因此我添加了以下代码来实现(当前是不安全的代理),

 HttpHost proxy = new HttpHost("localhost", 5555);
 httpClient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy);

This has worked fine with a non secure request. 对于不安全的请求,此方法运行良好。 However i am having trouble with a secure (https) request with the same code. 但是我在使用相同代码的安全(https)请求时遇到了麻烦。

Get the below exception (it tries a few time before failing), 获取以下异常(它会尝试几次才能失败),

Mar 12, 2014 11:14:27 AM org.apache.http.impl.client.DefaultRequestDirector tryConnect
INFO: I/O exception (org.apache.http.NoHttpResponseException) caught when connecting to the target host: The target server failed to respond
Mar 12, 2014 11:14:27 AM org.apache.http.impl.client.DefaultRequestDirector tryConnect
INFO: Retrying connect
org.apache.http.NoHttpResponseException: The target server failed to respond
    at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:95)
    at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:62)
    at org.apache.http.impl.io.AbstractMessageParser.parse(AbstractMessageParser.java:254)
    at org.apache.http.impl.AbstractHttpClientConnection.receiveResponseHeader(AbstractHttpClientConnection.java:289)
    at org.apache.http.impl.conn.DefaultClientConnection.receiveResponseHeader(DefaultClientConnection.java:252)
    at org.apache.http.impl.conn.ManagedClientConnectionImpl.receiveResponseHeader(ManagedClientConnectionImpl.java:191)
    at org.apache.http.protocol.HttpRequestExecutor.doReceiveResponse(HttpRequestExecutor.java:300)
    at org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:127)
    at org.apache.http.impl.client.DefaultRequestDirector.createTunnelToTarget(DefaultRequestDirector.java:899)
    at org.apache.http.impl.client.DefaultRequestDirector.establishRoute(DefaultRequestDirector.java:818)
    at org.apache.http.impl.client.DefaultRequestDirector.tryConnect(DefaultRequestDirector.java:644)
    at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:479)
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:906)
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:805)
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:784)
    at com.poc.test.SSLTest.main(SSLTest.java:88)

Tried following things, 尝试了以下事情,

  1. For https requests, i added both "http" as well as "https" to the schema registry, using the same SSLFactory as the one used for "https". 对于https请求,我使用与用于“ https”的SSLFactory相同的SSLFactory将“ http”和“ https”添加到架构注册表。
  2. Changed the proxy to, HttpHost proxy = new HttpHost("localhost", 5555, "https"); 将代理更改为HttpHost proxy = new HttpHost(“ localhost”,5555,“ https”);

However in both cases it failed with, 但是,在这两种情况下,它都失败了,

javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated
    at sun.security.ssl.SSLSessionImpl.getPeerCertificates(SSLSessionImpl.java:397)
    at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:128)
    at org.apache.http.conn.ssl.SSLSocketFactory.connectSocket(SSLSocketFactory.java:572)
    at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:180)
    at org.apache.http.impl.conn.ManagedClientConnectionImpl.open(ManagedClientConnectionImpl.java:294)
    at org.apache.http.impl.client.DefaultRequestDirector.tryConnect(DefaultRequestDirector.java:640)
    at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:479)
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:906)
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:805)
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:784)
    at com.poc.test.SSLTest.main(SSLTest.java:89)

Note - I am running a non secure proxy on my localhost via tcpmon. 注意-我正在通过tcpmon在本地主机上运行非安全代理。

EDIT : Here is the code i am using for the SSL with proxy communication, 编辑 :这是我用于SSL与代理通信的代码,

DefaultHttpClient httpClient = new DefaultHttpClient();

try {
    SSLContext ctx = SSLContext.getInstance("TLSv1.1");
    TrustManager[] trustManagers = getTrustManagers("jks", new FileInputStream(new File("C:\\SSLKeyStore.ks")), "changeit");
    ctx.init(null, trustManagers, new SecureRandom());

    HttpGet httpget = new HttpGet("https://localhost:8844/Channels/HTTP/getData");
    System.out.println("executing request" + httpget.getRequestLine());

    SSLSocketFactory factory = new SSLSocketFactory(ctx);
    factory.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);

    ClientConnectionManager manager = httpClient.getConnectionManager();
    manager.getSchemeRegistry().register(new Scheme("https", 443, factory));
    manager.getSchemeRegistry().register(new Scheme("http", 80, PlainSocketFactory.getSocketFactory()));

    HttpHost proxy = new HttpHost("localhost", 5555, "http");
    httpClient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy);

    HttpResponse response = httpClient.execute(httpget);
    HttpEntity entity = response.getEntity();

    System.out.println("----------------------------------------");
    System.out.println(response.getStatusLine());
    if (entity != null) {
        System.out.println("Response content length: " + entity.getContentLength());
    }
    EntityUtils.consume(entity);
} catch (Exception exception) {
    exception.printStackTrace();
} finally {
    httpClient.getConnectionManager().shutdown();
}

Any ideas of what is happening, what am i missing with respect to https and proxy. 关于正在发生的事情的任何想法,关于https和代理我缺少什么。

Latest EDIT - Even tried their example code (ClientExecuteProxy.java) as is, that too failed with proxy. 最新编辑 -甚至按原样尝试了示例代码(ClientExecuteProxy.java),但代理也失败了。 Is this functionality broken? 这个功能坏了吗?

HttpHost proxy = new HttpHost("127.0.0.1", 8080, "http");

    DefaultHttpClient httpclient = new DefaultHttpClient();
    try {
        httpclient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy);

        HttpHost target = new HttpHost("issues.apache.org", 443, "https");
        HttpGet req = new HttpGet("/");

        System.out.println("executing request to " + target + " via " + proxy);
        HttpResponse rsp = httpclient.execute(target, req);
        HttpEntity entity = rsp.getEntity();

        System.out.println("----------------------------------------");
        System.out.println(rsp.getStatusLine());
        Header[] headers = rsp.getAllHeaders();
        for (int i = 0; i<headers.length; i++) {
            System.out.println(headers[i]);
        }
        System.out.println("----------------------------------------");

        if (entity != null) {
            System.out.println(EntityUtils.toString(entity));
        }

    } finally {
        // When HttpClient instance is no longer needed,
        // shut down the connection manager to ensure
        // immediate deallocation of all system resources
        httpclient.getConnectionManager().shutdown();
    }
}

Thanks, Vicky 谢谢,Vicky

Off the top of my head I'd say that you are dealing with a certificate trust issue. 我想说的是,您正在处理证书信任问题。

Without seeing how you are setting up the connection specifically I can say with no certainty though. 但是,在没有看到您如何具体设置连接的情况下,我无法确定地说。

The "peer not authenticated" means that somewhere along the line the verification of the certificates as presented by one or more of the servers cannot be verified. “未对等身份验证”是指沿线某处无法验证由一个或多个服务器提供的证书的验证。

EDIT Since the proxy is under your control you have a load of flexibility at this time. 编辑由于代理处于您的控制之下,因此您现在拥有很大的灵活性。

Please see this SO article , it may suit your needs. 请参阅这篇SO文章 ,它可能适合您的需求。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM