`

Java的HttpClient如何去支持无证书访问https

阅读更多
项目里需要访问其他接口,通过http/https协议。我们一般是用HttpClient类来实现具体的http/https协议接口的调用。

// Init a HttpClient
HttpClient client = new HttpClient();
String url=http://www.xxx.com/xxx;

// Init a HttpMethod
HttpMethod get = new GetMethod(url);
get.setDoAuthentication(true);
get.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler(1, false));

// Call http interface
try {
    client.executeMethod(get);

    // Handle the response from http interface
    InputStream in = get.getResponseBodyAsStream();
    SAXReader reader = new SAXReader();
    Document doc = reader.read(in);
} finally {
    // Release the http connection
    get.releaseConnection();
}

以上代码在通过普通的http协议是没有问题的,但如果是https协议的话,就会有证书文件的要求了。一般情况下,是这样去做的。

// Init a HttpClient
HttpClient client = new HttpClient();
String url=https://www.xxx.com/xxx;

if (url.startsWith("https:")) {
    System.setProperty("javax.net.ssl.trustStore", "/.sis.cer");
    System.setProperty("javax.net.ssl.trustStorePassword", "public");
}

......

于是,这里就需要事先生成一个.sis.cer的文件,生成这个文件的方法一般是先通过浏览器访问https://,导出证书文件,再用JAVA keytool command 生成证书

# $JAVA_HOME/bin/keytool -import -file sis.cer -keystore .sis.cer

但这样做,一比较麻烦,二来证书也有有效期,过了有效期之后,又需要重新生成一次证书。如果能够避开生成证书文件的方式来使用https的话,就比较好了。

还好,在最近的项目里,我们终于找到了方法。

// Init a HttpClient
HttpClient client = new HttpClient();
String url=https://www.xxx.com/xxx;

if (url.startsWith("https:")) {
    this.supportSSL(url, client);
}

......

这里用到了supportSSL(url, client)这个方法,看看这个方法是如何实现的。

private void supportSSL(String url, HttpClient client) {
        if(StringUtils.isBlank(url)) {
            return;
        }
        String siteUrl = StringUtils.lowerCase(url);
        if (!(siteUrl.startsWith("https"))) {
            return;
        }
      
        try {
            setSSLProtocol(siteUrl, client);
        } catch (Exception e) {
            logger.error("setProtocol error ", e);
        }
        Security.setProperty( "ssl.SocketFactory.provider",
        "com.tool.util.DummySSLSocketFactory");
    }

private static void setSSLProtocol(String strUrl, HttpClient client) throws Exception {
      
        URL url = new URL(strUrl);
        String host = url.getHost();
        int port = url.getPort();

        if (port <= 0) {
            port = 443;
        }
        ProtocolSocketFactory factory = new SSLSocketFactory();
        Protocol authhttps = new Protocol("https", factory, port);
        Protocol.registerProtocol("https", authhttps);
        // set https protocol
        client.getHostConfiguration().setHost(host, port, authhttps);
    }

在supportSSL方法里,调用了Security.setProperty( "ssl.SocketFactory.provider",
        "com.tool.util.DummySSLSocketFactory");

那么这个com.tool.util.DummySSLSocketFactory是这样的:



访问https 资源时,让httpclient接受所有ssl证书,在weblogic等容器中很有用
代码如下:


Java代码

   1. import java.io.IOException; 
   2. import java.net.InetAddress; 
   3. import java.net.InetSocketAddress; 
   4. import java.net.Socket; 
   5. import java.net.SocketAddress; 
   6. import java.net.UnknownHostException; 
   7. import java.security.KeyManagementException; 
   8. import java.security.NoSuchAlgorithmException; 
   9. import java.security.cert.CertificateException; 
  10. import java.security.cert.X509Certificate; 
  11.  
  12. import javax.net.SocketFactory; 
  13. import javax.net.ssl.SSLContext; 
  14. import javax.net.ssl.TrustManager; 
  15. import javax.net.ssl.X509TrustManager; 
  16.  
  17. import org.apache.commons.httpclient.ConnectTimeoutException; 
  18. import org.apache.commons.httpclient.params.HttpConnectionParams; 
  19. import org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory; 
  20.  
  21. public class MySecureProtocolSocketFactory implements SecureProtocolSocketFactory { 
  22.     static{ 
  23.         System.out.println(">>>>in MySecureProtocolSocketFactory>>"); 
  24.     } 
  25.     private SSLContext sslcontext = null; 
  26.     
  27.     private SSLContext createSSLContext() { 
  28.         SSLContext sslcontext=null; 
  29.         try { 
  30.             sslcontext = SSLContext.getInstance("SSL"); 
  31.             sslcontext.init(null, new TrustManager[]{new TrustAnyTrustManager()}, new java.security.SecureRandom()); 
  32.         } catch (NoSuchAlgorithmException e) { 
  33.             e.printStackTrace(); 
  34.         } catch (KeyManagementException e) { 
  35.             e.printStackTrace(); 
  36.         } 
  37.         return sslcontext; 
  38.     } 
  39.     
  40.     private SSLContext getSSLContext() { 
  41.         if (this.sslcontext == null) { 
  42.             this.sslcontext = createSSLContext(); 
  43.         } 
  44.         return this.sslcontext; 
  45.     } 
  46.     
  47.     public Socket createSocket(Socket socket, String host, int port, boolean autoClose) 
  48.             throws IOException, UnknownHostException { 
  49.         return getSSLContext().getSocketFactory().createSocket( 
  50.                 socket, 
  51.                 host, 
  52.                 port, 
  53.                 autoClose 
  54.             ); 
  55.     } 
  56.  
  57.     public Socket createSocket(String host, int port) throws IOException, 
  58.             UnknownHostException { 
  59.         return getSSLContext().getSocketFactory().createSocket( 
  60.                 host, 
  61.                 port 
  62.             ); 
  63.     } 
  64.     
  65.     
  66.     public Socket createSocket(String host, int port, InetAddress clientHost, int clientPort) 
  67.             throws IOException, UnknownHostException { 
  68.         return getSSLContext().getSocketFactory().createSocket(host, port, clientHost, clientPort); 
  69.     } 
  70.  
  71.     public Socket createSocket(String host, int port, InetAddress localAddress, 
  72.             int localPort, HttpConnectionParams params) throws IOException, 
  73.             UnknownHostException, ConnectTimeoutException { 
  74.         if (params == null) { 
  75.             throw new IllegalArgumentException("Parameters may not be null"); 
  76.         } 
  77.         int timeout = params.getConnectionTimeout(); 
  78.         SocketFactory socketfactory = getSSLContext().getSocketFactory(); 
  79.         if (timeout == 0) { 
  80.             return socketfactory.createSocket(host, port, localAddress, localPort); 
  81.         } else { 
  82.             Socket socket = socketfactory.createSocket(); 
  83.             SocketAddress localaddr = new InetSocketAddress(localAddress, localPort); 
  84.             SocketAddress remoteaddr = new InetSocketAddress(host, port); 
  85.             socket.bind(localaddr); 
  86.             socket.connect(remoteaddr, timeout); 
  87.             return socket; 
  88.         } 
  89.     } 
  90.     
  91.     //自定义私有类 
  92.     private static class TrustAnyTrustManager implements X509TrustManager { 
  93.        
  94.         public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { 
  95.         } 
  96.    
  97.         public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { 
  98.         } 
  99.    
100.         public X509Certificate[] getAcceptedIssuers() { 
101.             return new X509Certificate[]{}; 
102.         } 
103.     }    
104.  
105. } 

import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.UnknownHostException;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

import javax.net.SocketFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import org.apache.commons.httpclient.ConnectTimeoutException;
import org.apache.commons.httpclient.params.HttpConnectionParams;
import org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory;

public class MySecureProtocolSocketFactory implements SecureProtocolSocketFactory {
    static{
        System.out.println(">>>>in MySecureProtocolSocketFactory>>");
    }
    private SSLContext sslcontext = null;
  
    private SSLContext createSSLContext() {
        SSLContext sslcontext=null;
        try {
            sslcontext = SSLContext.getInstance("SSL");
            sslcontext.init(null, new TrustManager[]{new TrustAnyTrustManager()}, new java.security.SecureRandom());
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (KeyManagementException e) {
            e.printStackTrace();
        }
        return sslcontext;
    }
  
    private SSLContext getSSLContext() {
        if (this.sslcontext == null) {
            this.sslcontext = createSSLContext();
        }
        return this.sslcontext;
    }
  
    public Socket createSocket(Socket socket, String host, int port, boolean autoClose)
            throws IOException, UnknownHostException {
        return getSSLContext().getSocketFactory().createSocket(
                socket,
                host,
                port,
                autoClose
            );
    }

    public Socket createSocket(String host, int port) throws IOException,
            UnknownHostException {
        return getSSLContext().getSocketFactory().createSocket(
                host,
                port
            );
    }
  
  
    public Socket createSocket(String host, int port, InetAddress clientHost, int clientPort)
            throws IOException, UnknownHostException {
        return getSSLContext().getSocketFactory().createSocket(host, port, clientHost, clientPort);
    }

    public Socket createSocket(String host, int port, InetAddress localAddress,
            int localPort, HttpConnectionParams params) throws IOException,
            UnknownHostException, ConnectTimeoutException {
        if (params == null) {
            throw new IllegalArgumentException("Parameters may not be null");
        }
        int timeout = params.getConnectionTimeout();
        SocketFactory socketfactory = getSSLContext().getSocketFactory();
        if (timeout == 0) {
            return socketfactory.createSocket(host, port, localAddress, localPort);
        } else {
            Socket socket = socketfactory.createSocket();
            SocketAddress localaddr = new InetSocketAddress(localAddress, localPort);
            SocketAddress remoteaddr = new InetSocketAddress(host, port);
            socket.bind(localaddr);
            socket.connect(remoteaddr, timeout);
            return socket;
        }
    }
  
    //自定义私有类
    private static class TrustAnyTrustManager implements X509TrustManager {
     
        public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
        }
 
        public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
        }
 
        public X509Certificate[] getAcceptedIssuers() {
            return new X509Certificate[]{};
        }
    }  

}



然后按如下方式使用HttpClient

Protocol myhttps = new Protocol("https", new MySecureProtocolSocketFactory (), 443);
Protocol.registerProtocol("https", myhttps);
HttpClient httpclient=new HttpClient();
之后就是照常使用了,不知道怎样用的话,参考我的其它文章
分享到:
评论
1 楼 alosin 2011-03-18  
那httpclient 4 已经取消了protocol,该怎么办呢,研究了很久,网上的资料都不行

相关推荐

    java实现读取证书访问https接口

    本篇文章将深入探讨如何在Java中实现读取不同格式(如cer、der、crt)的证书,以及如何使用这些证书访问HTTPS接口并获取返回数据。 首先,我们需要了解证书的基本概念。证书通常包含了公钥和一些身份信息,由受信任...

    httpclient访问需要客户端认证数字证书的https接口的处理方法

    默认的`SSLProtocolSocketFactory`并不支持客户端证书,所以我们需要创建一个扩展,覆盖其`createSocket()`方法,以便在建立连接时设置客户端证书。在这个自定义实现中,你需要加载之前安装的客户端证书和私钥,然后...

    HttpClient4.5 实现https忽略SSL证书验证

    使用HttpClient4.5实现https请求忽略SSL证书验证工具类

    httpclient来进行https访问

    要使`httpclient`支持HTTPS访问,首先需要配置SSL上下文。这通常涉及到证书管理、密钥存储以及信任管理等环节。 ### 关键技术细节 #### 3.1 配置SSL上下文 在`httpclient`中使用HTTPS,首先要解决的是SSL上下文的...

    Android使用HttpClient和HttpsUrlConnection两种方式访问https网站

    本文将详细介绍如何使用`HttpClient`和`HttpsURLConnection`两种方式来访问HTTPS网站,包括验证证书和不验证证书的实现方法。 ### 1. Android中的HttpClient `HttpClient`是Apache提供的一种HTTP客户端库,它支持...

    httpclient4.5 绕过ssl认证文件访问

    本篇文章将详细讲解如何在HTTPClient 4.5版本中绕过SSL(Secure Sockets Layer)认证,实现对HTTPS网站的访问。 首先,了解SSL/TLS(Transport Layer Security)协议的重要性。SSL/TLS是网络安全传输的标准,它通过...

    Java Https请求,跳过证书,直接访问

    至于提到的"相关jar包全有",这可能指的是用于处理HTTPS请求和SSL连接的Java标准库(如`javax.net.ssl.*`)以及其他可能需要的第三方库,如Apache HttpClient。"TestHttp"可能是一个测试HTTP请求的Java类或文件,你...

    使用httpclient无需证书调用https的示例(java调用https)

    以下是一个使用HttpClient进行无证书验证调用HTTPS的示例。 首先,我们需要创建一个自定义的`SSLSocketFactory`,该工厂会忽略证书验证。这通常不推荐用于生产环境,因为它可能导致安全漏洞,但在测试或调试时非常...

    使用httpClient访问https+443端口号。

    标题中的“使用httpClient访问https+443端口号”指的是使用Apache HttpClient库来发起HTTPS(安全超文本传输协议)请求,目标服务器的默认端口是443。HTTPS是一种基于SSL/TLS的安全通信协议,用于在客户端和服务器...

    java使用HttpClient通过url下载文件到本地

    HttpClient是一个Java库,支持HTTP/1.1协议以及部分HTTP/2特性。它提供了一组高级API,用于处理HTTP请求和响应,包括重试、连接管理、超时设置等。对于网络编程,HttpClient是一个高效且灵活的选择。 2. **Eclipse...

    java访问https网址下载文件(含证书)

    当你访问HTTPS站点时,Java默认的TrustStore可能不包含特定服务器的证书,因此需要自定义SSL上下文。首先,你需要将服务器的证书导入到一个信任库文件(如JKS或PKCS12格式),然后创建一个`SSLContext`对象,并设置...

    JAVA利用HttpClient进行HTTPS接口调用的方法

    Java中使用HttpClient进行HTTPS接口调用的方法是通过继承DefaultHttpClient类,忽略证书校验过程。首先,创建一个SSLClient类,继承DefaultHttpClient类,并在构造函数中初始化SSLContext和TrustManager。然后,使用...

    httpclient4.1访问https的配置方法

    【标题】:“httpclient4.1访问https的配置方法” 【描述】:“本教程将指导你如何利用Apache HttpClient 4.1实现对HTTPS服务的访问,首先需要在Tomcat服务器上配置SSL支持。我们将涵盖SSL证书的生成、Tomcat服务器...

    Java 生成证书工具类 https

    java生成https安全证书,解决httpClient访问https出错 编译:javac InstallCert.java 运行:java InstallCert 要访问的网址 结果:Enter certificate to add to trusted keystore or 'q' to quit: [1] 输入1确认生成...

    使用httpclient访问servlet

    如果Servlet需要HTTPS(SSL/TLS)加密,HttpClient需要配置SSLContext和TrustStrategy,处理证书和信任问题。 10. **最佳实践**: - 关闭响应实体和HttpClient实例以释放资源。 - 避免长时间持有HttpClient实例...

    基于HttpClient 4.3的可访问自签名HTTPS站点的新版工具类

    另外在项目中正好需要访问https协议的接口,而对应的服务器没有购买商业CA颁发的正式受信证书,只是做了个自签名(联想一下12306网站购票时提示的那个警告信息),默认情况下通过HttpClient访问会抛出异常。...

    httpClient,JAVA访问http request response

    在JAVA中使用HttpClient访问HTTP请求并处理response,涉及到的主要知识点包括: 1. **HttpClient的基本使用**: - 创建HttpClient实例:通常使用`HttpClientBuilder`或`HttpClients`类创建HttpClient对象。 - ...

    HttpClient依赖jar包.zip

    4. **支持SSL/TLS**:HttpClient内置了对HTTPS的支持,可以处理SSL证书验证,确保数据传输的安全性。 5. **重试策略**:当网络不稳定或服务器短暂故障时,HttpClient可以设置重试策略,自动处理请求失败的情况。 6...

    keytool httpclient https所需jar包

    在使用这些JAR文件时,你需要将它们添加到你的项目类路径中,以便你的程序能够访问和使用`keytool`和`httpclient`的相关功能。如果你正在使用Maven或Gradle构建系统,你可以通过在你的构建配置文件中声明依赖来引入...

    java根证书认证实现https访问

    在Java中实现根证书认证以安全地访问HTTPS服务是一个关键的步骤,特别是在处理敏感数据或者进行服务器间通信时。HTTPS协议提供了对传输数据的加密,确保了数据在互联网上的完整性和机密性。本篇文章将深入探讨如何在...

Global site tag (gtag.js) - Google Analytics