簡體   English   中英

Apache Http Client 4.0.1 SSL代理

[英]Apache Http Client 4.0.1 SSL Proxy

我正在使用Apache Http客戶端4.0.1與服務器進行通信。 我已經有一個安全/不安全的客戶端代碼,可以正常工作。

最近,新增加的功能是向此代碼添加代理,因此我添加了以下代碼來實現(當前是不安全的代理),

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

對於不安全的請求,此方法運行良好。 但是我在使用相同代碼的安全(https)請求時遇到了麻煩。

獲取以下異常(它會嘗試幾次才能失敗),

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)

嘗試了以下事情,

  1. 對於https請求,我使用與用於“ https”的SSLFactory相同的SSLFactory將“ http”和“ https”添加到架構注冊表。
  2. 將代理更改為HttpHost proxy = new HttpHost(“ localhost”,5555,“ https”);

但是,在這兩種情況下,它都失敗了,

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)

注意-我正在通過tcpmon在本地主機上運行非安全代理。

編輯 :這是我用於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();
}

關於正在發生的事情的任何想法,關於https和代理我缺少什么。

最新編輯 -甚至按原樣嘗試了示例代碼(ClientExecuteProxy.java),但代理也失敗了。 這個功能壞了嗎?

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();
    }
}

謝謝,Vicky

我想說的是,您正在處理證書信任問題。

但是,在沒有看到您如何具體設置連接的情況下,我無法確定地說。

“未對等身份驗證”是指沿線某處無法驗證由一個或多個服務器提供的證書的驗證。

編輯由於代理處於您的控制之下,因此您現在擁有很大的靈活性。

請參閱這篇SO文章 ,它可能適合您的需求。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM