`

HttpClient https

阅读更多
Introduction

HttpClient provides full support for HTTP over Secure Sockets Layer (SSL) or IETF Transport Layer Security (TLS) protocols by leveraging the Java Secure Socket Extension (JSSE). JSSE has been integrated into the Java 2 platform as of version 1.4 and works with HttpClient out of the box. On older Java 2 versions JSSE needs to be manually installed and configured. Installation instructions can be found here
Standard SSL in HttpClient

Once you have JSSE correctly installed, secure HTTP communication over SSL should be as simple as plain HTTP communication.

  HttpClient httpclient = new HttpClient();
  GetMethod httpget = new GetMethod("https://www.verisign.com/");
  try {
    httpclient.executeMethod(httpget);
    System.out.println(httpget.getStatusLine());
  } finally {
    httpget.releaseConnection();
  }

HTTPS communication via an authenticating proxy server is also no different from plain HTTP communication. All the low-level details of establishing a tunneled SSL connection are handled by HttpClient:

  HttpClient httpclient = new HttpClient();
  httpclient.getHostConfiguration().setProxy("myproxyhost", 8080);
  httpclient.getState().setProxyCredentials("my-proxy-realm", " myproxyhost",
  new UsernamePasswordCredentials("my-proxy-username", "my-proxy-password"));
  GetMethod httpget = new GetMethod("https://www.verisign.com/");
  try {
    httpclient.executeMethod(httpget);
    System.out.println(httpget.getStatusLine());
  } finally {
    httpget.releaseConnection();
  }

Customizing SSL in HttpClient

The default behaviour of HttpClient is suitable for most uses, however there are some aspects which you may want to configure. The most common requirements for customizing SSL are:

    * Ability to accept self-signed or untrusted SSL certificates. This is highlighted by an SSLException with the message Unrecognized SSL handshake (or similar) being thrown when a connection attempt is made.
    * You want to use a third party SSL library instead of Sun's default implementation.

Implementation of a custom protocol involves the following steps:

   1.

      Provide a custom socket factory that implements org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory interface. The socket factory is responsible for opening a socket to the target server using either the standard or a third party SSL library and performing any required initialization such as performing the connection handshake. Generally the initialization is performed automatically when the socket is created.
   2.

      Instantiate an object of type org.apache.commons.httpclient.protocol.Protocol. The new instance would be created with a valid URI protocol scheme (https in this case), the custom socket factory (discussed above) and a default port number (typically 443 for https). For example:

      Protocol myhttps = new Protocol("https", new MySSLSocketFactory(), 443);
           

      The new instance of protocol can then be set as the protocol handler for a HostConfiguration. For example to configure the default host and protocol handler for a HttpClient instance use:

      HttpClient httpclient = new HttpClient();
      httpclient.getHostConfiguration().setHost("www.whatever.com", 443, myhttps);
      GetMethod httpget = new GetMethod("/");
      try {
        httpclient.executeMethod(httpget);
        System.out.println(httpget.getStatusLine());
      } finally {
        httpget.releaseConnection();
      }

   3.

      Finally, you can register your custom protocol as the default handler for a specific protocol designator (eg: https) by calling the Protocol.registerProtocol method. You can specify your own protocol designator (such as 'myhttps') if you need to use your custom protocol as well as the default SSL protocol implementation.

      Protocol.registerProtocol("myhttps",
      new Protocol("https", new MySSLSocketFactory(), 9443));
           

      Once registered the protocol be used as a 'virtual' scheme inside target URIs.

      HttpClient httpclient = new HttpClient();
      GetMethod httpget = new GetMethod("myhttps://www.whatever.com/");
      try {
        httpclient.executeMethod(httpget);
        System.out.println(httpget.getStatusLine());
      } finally {
        httpget.releaseConnection();
      }

      If you want this protocol to represent the default SSL protocol implementation, simply register it under 'https' designator, which will make the protocol object take place of the existing one

      Protocol.registerProtocol("https",
      new Protocol("https", new MySSLSocketFactory(), 443));
      HttpClient httpclient = new HttpClient();
      GetMethod httpget = new GetMethod("https://www.whatever.com/");
      try {
        httpclient.executeMethod(httpget);
        System.out.println(httpget.getStatusLine());
      } finally {
        httpget.releaseConnection();
      }

Examples of SSL customization in HttpClient

There are several custom socket factories available in our contribution package. They can be a good start for those who seek to tailor the behavior of the HTTPS protocol to the specific needs of their application:

    * EasySSLProtocolSocketFactory can be used to create SSL connections that allow the target server to authenticate with a self-signed certificate.
    * StrictSSLProtocolSocketFactory can be used to create SSL connections that can optionally perform host name verification in order to help preventing man-in-the-middle type of attacks.
    * AuthSSLProtocolSocketFactory can be used to optionally enforce mutual client/server authentication. This is the most flexible implementation of a protocol socket factory. It allows for customization of most, if not all, aspects of the SSL authentication.

Known limitations and problems

   1.

      Persistent SSL connections do not work on Sun's JVMs below 1.4

      Due to what appears to be a bug in Sun's older (below 1.4) implementation of Java Virtual Machines or JSSE there's no reliable way of telling if an SSL connection is 'stale' or not. For example, the HTTP 1.1 specification permits HTTP servers in 'keep-alive' mode to drop the connection to the client after a given period inactivity without having to notify the client, effectively rendering such connection unusable or 'stale'. For the HTTP agent written in Java there's no reliable way to test if a connection is 'stale' other than attempting to perform a read on it. However, a read operation on an idle SSL connection on Sun JVM older than 1.4 returns 'end of stream' instead of an expected read timeout. That effectively makes the connection appear 'stale' to HttpClient, which leaves it with no other way but to drop the connection and to open a new one, thus defeating HTTP 1.1 keep-alive mechanism and resulting in significant performance degradation (SSL authentication is a highly time consuming operation). The problem appears to have been fixed in Sun's Java 1.4 SSL implementation. Sockets which are not using HTTPS are unaffected on any JVM.

      Workaround: Disable stale connection check if upgrade to Java 1.4 or above is not an option. Please note that HttpClient will no longer be able to detect invalid connections and some requests may fail due to transport errors. For details on how transport errors can be recovered from please refer to the Exception Handling Guide. If persistent SSL connections support and transport reliability is an issue for your application we strongly advise you to upgrade to Java 1.4.
   2.

      Authetication schemes that rely on persistent connection state do not work on Sun's JVMs below 1.4 if SSL is used

      This problem is directly related to the problem described above. Certain authentication schemes or certain implementations of standard authentication schemes are connection based, that is, the user authentication is performed once when the connection is being established, rather than every time a request is being processed. Microsoft NTLM scheme and Digest scheme as implemented in Microsoft Proxy and IIS servers are known to fall into this category. If connections cannot be kept alive the user authorization is lost along with the persistent connection state

      Workaround: Disable stale connection check or upgrade to Java 1.4 or above.
   3.

      JSSE prior to Java 1.4 incorrectly reports socket timeout.

      Prior to Java 1.4, in Sun's JSSE implementation, a read operation that has timed out incorrect reports end of stream condition instead of throwing java.io.InterruptedIOException as expected. HttpClient responds to this exception by assuming that the connection was dropped and throws a NoHttpResponseException. It should instead report "java.io.InterruptedIOException: Read timed out". If you encounter NoHttpResponseException when working with an older version of JDK and JSSE, it can be caused by the timeout waiting for data and not by a problem with the connection.

      Work-around: One possible solution is to increase the timeout value as the server is taking too long to start sending the response. Alternatively you may choose to upgrade to Java 1.4 or above which does not exhibit this problem.

      The problem has been discovered and reported by Daniel C. Amadei.
   4.

      HttpClient does not work with IBM JSSE shipped with IBM Websphere Application Platform

      Several releases of the IBM JSSE exhibit a bug that cause HttpClient to fail while detecting the size of the socket send buffer (java.net.Socket.getSendBufferSize method throws java.net.SocketException: "Socket closed" exception).

      Solution: Make sure that you have all the latest Websphere fix packs applied and IBMJSSE is at least version 1.0.3. HttpClient users have reported that IBM Websphere Application Server versions 4.0.6, 5.0.2.2, 5.1.0 and above do not exhibit this problem.

Troubleshooting

JSSE is prone to configuration problems, especially on older JVMs, which it is not an integral part of. As such, if you do encounter problems with SSL and HttpClient it is important to check that JSSE is correctly installed.

The application below can be used as an ultimate test that can reliably tell if SSL configured properly, as it relies on a plain socket in order to communicate with the target server. If an exception is thrown when executing this code, SSL is not correctly installed and configured. Please refer to Sun's official resources for support or additional details on JSSE configuration.

  import java.io.BufferedReader;
  import java.io.InputStreamReader;
  import java.io.OutputStreamWriter;
  import java.io.Writer;
  import java.net.Socket;

  import javax.net.ssl.SSLSocketFactory;

  public class Test {
       
     public static final String TARGET_HTTPS_SERVER = "www.verisign.com";
     public static final int    TARGET_HTTPS_PORT   = 443;
       
     public static void main(String[] args) throws Exception {
       
       Socket socket = SSLSocketFactory.getDefault().
         createSocket(TARGET_HTTPS_SERVER, TARGET_HTTPS_PORT);
       try {
         Writer out = new OutputStreamWriter(
            socket.getOutputStream(), "ISO-8859-1");
         out.write("GET / HTTP/1.1\r\n"); 
         out.write("Host: " + TARGET_HTTPS_SERVER + ":" +
             TARGET_HTTPS_PORT + "\r\n"); 
         out.write("Agent: SSL-TEST\r\n"); 
         out.write("\r\n"); 
         out.flush(); 
         BufferedReader in = new BufferedReader(
            new InputStreamReader(socket.getInputStream(), "ISO-8859-1"));
         String line = null;
         while ((line = in.readLine()) != null) {
            System.out.println(line);
         }
       } finally {
         socket.close();
       }
     }
  }
       

分享到:
评论

相关推荐

    HttpClient Https实战

    HttpClient是Apache基金会开发的一个Java库,用于执行HTTP和HTTPS请求。在实际的IT工作中,HttpClient是一个非常重要的工具,尤其在需要进行HTTP通信或者自动化测试时。这篇博客“HttpClient Https实战”很可能详细...

    JAVA利用HttpClient进行HTTPS接口调用

    当涉及到HTTPS接口调用时,HttpClient可以处理加密通信,确保数据传输的安全性。在这个主题中,我们将深入探讨如何在Java中使用HttpClient来实现HTTPS接口调用。 首先,我们需要理解HTTPS协议。HTTPS是HTTP(超文本...

    httpclient4.5发送https请求(验证证书)

    不会的可以在评论区留言哈,这是我自己做项目用到的。所以绝对可用!同时共享出来给到大家

    httpClient连接https 获得验证码图片示例

    httpClient连接https 获得验证码图片示例 需要证书才能连接的那种 /* 本文所用开发工具 jak1.5.0_06 eclipse:ObjectWeb Lomboz lib: commons-codec-1.4.jar commons-logging-1.1.jar httpclient-4.0.3.jar ...

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

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

    keytool httpclient https所需jar包

    本资源包包含了`keytool`和`httpclient`相关的JAR文件,这些都是实现HTTPS通信所必需的工具和库。 `keytool`是Java开发工具包(JDK)自带的一个命令行工具,主要用于管理密钥对和数字证书。它允许用户创建、导入、...

    java httpclient https或http及文件中转上传工具类

    该工具类使用httpclient进行http or https请求,包括requestbody格式和form表单格式,另外含文件服务器中转上传方法,几乎支持所有常用接口调用,内含详细注释和说明文件,含jar包,及maven方式引用,拿过去直接用吧

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

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

    esp8266 发起https 请求

    - 在ESP8266上实现HTTPS请求,需要使用支持SSL/TLS的库,如Arduino的`ESP8266HTTPClient`库。 - `ESP8266HTTPClient`库提供了一个API,允许开发者轻松地发起GET、POST等HTTP请求,并处理响应。 3. **使用ESP8266...

    HttpClient之Https应用实例

    HttpClient之Https应用实例~ 包含: HttpClient 使用代理访问Https HttpClient 信任所有主机-对于任何证书都不做检查 HttpClient 允许所有证书的校验(包括过期证书)

    httpClient实例httpClient调用 http/https实例 忽略SSL验证

    在IT行业中,HttpClient是一个常用的Java库,用于执行HTTP和HTTPS请求。这个实例主要涉及如何配置HttpClient来忽略SSL(Secure Socket Layer)验证,这对于在开发和测试环境中处理自签名证书或未认证的服务器非常...

    HttpClient发起HTTPs请求.rar

    在这个"HttpClient发起HTTPs请求.rar"压缩包中,我们主要关注的是如何利用HttpClient处理HTTPS协议的GET和POST请求,以及如何处理返回的JSON数据。这里,我们将详细讨论相关知识点。 首先,HTTPS是一种基于SSL/TLS...

    httpclient 绕开HTTPS证书校验

    总之,`httpclient`库提供了绕过HTTPS证书校验的能力,这在特定场景下很有用。然而,这种做法应该谨慎使用,并且只限于测试和非生产环境,因为这会削弱原本的加密保护,使数据易受攻击。在实际应用中,应确保使用...

    Android调用大宝CA国密SSL密码套件(0.99版本)访问HTTPS(国密SSL安全通道)的示例代码

    使用方法见:...1. Android使用HTTPCLIENT访问国密SSL协议的HTTPS服务 2. 示例代码为单向认证,可支持双向认证 3. 获取服务端的国密数字证书 4. 适用于Android 7.0(API 24)及以上

    httpclient来进行https访问

    根据提供的文件信息,我们可以深入探讨如何使用`httpclient`库来进行`https`访问,并了解其中涉及的关键概念和技术细节。 ### 标题与描述解析:使用`httpclient`进行`https`访问 #### 1. `httpclient`简介 `...

    基于c++11 httpclient

    https://github.com/iEternity/HttpClient github上是基于win的,附件为linux平台,以及android源码环境生成的主机host bin程序,在android 8.1,linux14.04环境均编译通过 内含CMakelists Android.mk文件

    android HttpClient访问Https

    android HttpClient访问某些Https时,出现了问题,无法访问,好像是要安全验证。此Demo解决了此问题,HttpClient能够Https和Http类型的URL了。 在eclipse下打开工程若有乱码,请把eclipse的字符编码改成UTF-8。

    httpClient自动接受https的证书代码

    HttpClient是一个流行的Java库,用于执行HTTP和HTTPS请求。当我们使用HttpClient进行HTTPS请求时,有时会遇到证书相关的问题,如服务器证书不受信任或未被系统信任的CA(证书权威机构)签发。本篇将详细介绍如何配置...

    (完整版)JAVA利用HttpClient进行POST请求(HTTPS).doc

    "JAVA利用HttpClient进行POST请求(HTTPS)" JAVA HttpClient是Apache软件基金会提供的一个开源实现HTTP客户端的Java库,能够帮助开发者轻松地与HTTP服务器进行交互。在实际项目中,我们经常需要使用HttpClient来发送...

    HttpClientUtil工具类发送get和post请求,支持http和https,支持发送文件

    3. 支持http和https:HttpClientUtil需要能够处理HTTP和HTTPS协议。HTTP协议不涉及数据加密,而HTTPS协议在HTTP的基础上加入了SSL/TLS层,提供数据加密和服务器身份验证,确保通信安全。HttpClient支持SSL/TLS,只需...

Global site tag (gtag.js) - Google Analytics