java - 使用 apache http 客户端通过代理的 HTTPs

标签 java apache http ssl

我有一个基于 apache http 客户端的 http 客户端,它似乎对 ssl 证书没有问题。我使用自定义 SSLSocketFactory 对全局认可的证书和自签名证书进行了单元测试。

然而,当我在代理后面运行相同的代码时,它停止工作了。我一直收到这个可怕的异常:

javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated
at com.sun.net.ssl.internal.ssl.SSLSessionImpl.getPeerCertificates(SSLSessionImpl.java:352)
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)

我将代码减少到最低限度,但它仍然抛出相同的异常。代码:

    URI uri = new URI("https://www.google.com");
    DefaultHttpClient client = new DefaultHttpClient();
    client.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, 
            new HttpHost("proxy.int", 8080, "https"));

    HttpUriRequest request = new HttpGet(uri);
    HttpResponse response = client.execute(request);

如果没有指定,我不确定它是否使用默认的 ssl 设置,所以我也明确地添加了它:

    URI uri = new URI("https://www.google.com");
    DefaultHttpClient client = new DefaultHttpClient();
    client.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, 
            new HttpHost("proxy.int", 8080, "https"));

    client.getConnectionManager().getSchemeRegistry().register(
            new Scheme("https", 443, SSLSocketFactory.getSystemSocketFactory()));

    HttpUriRequest request = new HttpGet(uri);
    HttpResponse response = client.execute(request);

我也尝试了 getSocketFactory()(不完全确定与 getSystemSocketFactory() 有什么区别),但仍然是同样的错误。

编辑:

代理有可选的身份验证,我已经尝试过有和没有。使用以下代码设置身份验证信息:

    client.getCredentialsProvider().setCredentials(
        new AuthScope("proxy.int", 8080),
        new UsernamePasswordCredentials("user", "password")
    );

完全一样的错误。

最佳答案

问题出在代理声明中,我必须指定“http”而不是“https”:

client.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, 
        new HttpHost("proxy.int", 8080, "http"));

关于java - 使用 apache http 客户端通过代理的 HTTPs,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12314361/

相关文章:

java - 如何在 Wiremock Servlet 上启用响应模板?

Django 1.8 App 在添加 SSL 时显示文件夹结构

php - 如何正确安装LAMP软件包?

asp.net - 截至目前,可用的编译服务器端语言有哪些?

django - 在 Django 中,如何确定请求是否已被取消?

java - 如何在 Android 上使用 SHA-256

java - 仅检查每个实例一个的最快方法?

java - Android Studio 无法读取文件,该文件不存在

rest - 为什么我的请求方法 GET 不受支持?

java - "Write operations are not allowed in read-only mode"错误 : confused with Spring @Service @transaction @Repository and Hibernate