commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mbe...@apache.org
Subject cvs commit: jakarta-commons/httpclient/xdocs sslguide.xml navigation.xml
Date Thu, 12 Jun 2003 03:31:51 GMT
mbecke      2003/06/11 20:31:50

  Modified:    httpclient/xdocs navigation.xml
  Added:       httpclient/xdocs sslguide.xml
  Log:
  Added SSL Guide.
  
  PR: 10809
  Submitted by: Oleg Kalnichevski
  
  Revision  Changes    Path
  1.8       +2 -1      jakarta-commons/httpclient/xdocs/navigation.xml
  
  Index: navigation.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/httpclient/xdocs/navigation.xml,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- navigation.xml	1 Jun 2003 18:51:23 -0000	1.7
  +++ navigation.xml	12 Jun 2003 03:31:50 -0000	1.8
  @@ -24,6 +24,7 @@
           <item name="Logging Guide" href="/logging.html"/>
           <item name="Methods" href="/methods.html"/>
           <item name="Sample Code" href="http://cvs.apache.org/viewcvs/jakarta-commons/httpclient/src/examples/"/>
  +        <item name="SSL Guide" href="/sslguide.html"/>
           <item name="Threading" href="/threading.html"/>
           <item name="Trouble Shooting" href="/troubleshooting.html"/>
           <item name="Tutorial" href="/tutorial.html"/>
  
  
  
  1.1                  jakarta-commons/httpclient/xdocs/sslguide.xml
  
  Index: sslguide.xml
  ===================================================================
  <?xml version="1.0" encoding="ISO-8859-1"?>
  
  <document>
    
    <properties>
      <title>HttpClient SSL Guide</title>
      <author email="oleg@ural.ru">Oleg Kalnichevski</author>
      <revision>$Id: sslguide.xml,v 1.1 2003/06/12 03:31:50 mbecke Exp $</revision>
    </properties>
  
    <body>
  
      <section name="Introduction">
       
       <p>
         HttpClient provides full support for HTTP over Secure Sockets Layer (SSL) or IETF
Transport Layer
         Security (TLS) protocols by leveraging the <a href="http://java.sun.com/products/jsse/index.html">
         Java Secure Socket Extension (JSSE)</a>. JSSE has been integrated into the
Java 2 platform as of 
         version 1.4 and usually should work with HttpClient out of the box. On older Java
2 versions JSSE 
         needs to be manually installed and configured. Installation instructions can be found
         <a href="http://java.sun.com/products/jsse/doc/guide/API_users_guide.html#Installation">here</a>
       </p>
  
      </section>
  
      <section name="Standard SSL in HttpClient">
        <p>
          With SSL properly set up and configured, secure HTTP communication over SSL should
be as simple 
          as plain HTTP communication. 
        </p>
        <source><![CDATA[
    HttpClient httpclient = new HttpClient();
    GetMethod httpget = new GetMethod("https://www.verisign.com/"); 
    httpclient.executeMethod(httpget);
    System.out.println(httpget.getStatusLine().toString());
        ]]></source>
        
        <p>
          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 abstracted 
          away by HttpClient:
        </p>
  
        <source><![CDATA[
    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/"); 
    httpclient.executeMethod(httpget);
    System.out.println(httpget.getStatusLine().toString());
        ]]></source>
  
      </section>
  
  
      <section name="Customizing SSL in HttpClient">
        
        <p>
         Per default HTTP client does not perform any custom certificate or certificate chain
validation.
         The default HTTPS protocol implementation is completely reliant upon the standard
functionality 
         of the JSSE that comes with the JVM. If your application requires some additional
processing of 
         credentials such certificate verification or certificate chain validation, or you
want to be using
         a third party SSL library, you can augment HttpClient to meet your specific requirements
by providing
         a custom protocol implementation. 
        </p>
  
        <p>
         Implementation of a custom protocol involves the following steps:
        </p>
  
        <ul>
  
          <li>
           <p>
           Provide a custom socket factory that implements 
           <a href="apidocs/org/apache/commons/httpclient/protocol/SecureProtocolSocketFactory.html">
           org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory</a> interface.
The socket 
           factory should encapsulate application specific aspects of opening a socket to
the target server 
           using either standard or third party SSL library. 
           </p>
          </li>
  
          <li>
           <p>
           Instantiate an object of type <a href="apidocs/org/apache/commons/httpclient/protocol/Protocol.html">
           org.apache.commons.httpclient.protocol.Protocol</a>. The new instance would
be initialized with the 
           following parameters: valid URI protocol scheme (https in this case), custom socket
factory discussed 
           above, and a default port number.
           </p>
  
          <source><![CDATA[
    Protocol myhttps = new Protocol("https", new MySSLSocketFactory(), 443);
          ]]></source>
  
          <p>
          The resultant protocol object then can be used as a default protocol for a host.
          </p>
  
          <source><![CDATA[
    HttpClient httpclient = new HttpClient();
    httpclient.getHostConfiguration().setHost("www.whatever.com", 443, myhttps);
    GetMethod httpget = new GetMethod("/");
    httpclient.executeMethod(httpget);
          ]]></source>
  
          </li>
  
          <li>
           <p>
            Optionally register the custom protocol by calling Protocol.registerProtocol method.
You can 
            specify your own protocol designator (such as 'myhttps') if you are going to be
using this protocol 
            along with the default SSL protocol implementation. 
           </p>
  
          <source><![CDATA[
    Protocol.registerProtocol("myhttps", 
    new Protocol("https", new MySSLSocketFactory(), 9443));
          ]]></source>
  
           <p>
            Once registered the protocol be used as a 'virtual' scheme inside target URIs.
           </p>
  
          <source><![CDATA[
    HttpClient httpclient = new HttpClient();
    GetMethod httpget = new GetMethod("myhttps://www.whatever.com/");
    httpclient.executeMethod(httpget);
          ]]></source>
  
          <p>
           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
          </p>
   
          <source><![CDATA[
    Protocol.registerProtocol("https", 
    new Protocol("https", new MySSLSocketFactory(), 443));
    HttpClient httpclient = new HttpClient();
    GetMethod httpget = new GetMethod("https://www.whatever.com/");
    httpclient.executeMethod(httpget);
          ]]></source>
  
          </li>
  
        </ul>
  
      </section>
  
      <section name="Examples of SSL customization in HttpClient">
        
        <p>
         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:
        </p>
  
        <ul>
  
          <li>
           <a href="http://cvs.apache.org/viewcvs/jakarta-commons/httpclient/src/contrib/org/apache/commons/httpclient/contrib/ssl/EasySSLProtocolSocketFactory.java?rev=HEAD">
 
            EasySSLProtocolSocketFactory</a> can be used to create SSL connections that
allow the target 
            server to authenticate with a self-signed certificate.
          </li>
  
          <li>
           <a href="http://cvs.apache.org/viewcvs/jakarta-commons/httpclient/src/contrib/org/apache/commons/httpclient/contrib/ssl/StrictSSLProtocolSocketFactory.java?rev=HEAD">
 
            StrictSSLProtocolSocketFactory</a> 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. 
          </li>
  
        </ul>
      
      </section>
  
      <section name="Known limitations and problems">
  
        <ol>
  
          <li>
           <p>
            <strong>Persistent SSL connections do not work on Sun's JVMs below 1.4</strong>
           </p>
       
           <p>
           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 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 known to us
to test 
           if a connection is 'stale' other than attempting to perform a read on it. If you
happen 
           to know a better way we would be delighted to hear about it. Rather unfortunately,
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 the 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).
Sun's 
           Java 1.4 SSL implementation does not exhibit this kind of problem. Plain sockets
on all
           JVMs are not subject to the problem either.
           </p>
           <p>
           <strong>Workaround:</strong> If persistent SSL connections support
is an issue for your 
           application we strongly advise you to upgrade to Java 1.4.
           </p>
          </li>
  
          <li>
          <p>
           <strong>Non-preemptive authentication with a HTTPS server fails when connecting
via a proxy</strong>
          </p>
  
          <p>
           This problem is caused by a serious flaw in HttpClient design and cannot be fixed
without
           breaking the existing APIs. The problem will be addressed in HttpClient release
2.1.
          </p>
          <p>
           <strong>Workaround:</strong> Use preemptive server authentication.
Please note that only 
            BASIC authentication can be used preemptively. For more detailed information please
refer 
            to the <a href="authentication.html">Authentication Guide</a>.
          </p>
          </li>
  
        </ol>
   
      </section>
   
      <section name="Troubleshooting">
  
         <p>
          If you are unlucky and HTTPS with HttpClient does not work for you, it may be a
bit premature 
          to blame it squarely on HttpClient. The JSSE is highly prone to configuration problems,
especially
          on older JVMs, which it is not an integral part of. 
         </p>
  
         <p>
          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 you 
          get an exception while executing this code, most certainly SSL is not functioning
properly with 
          your JVM. Please refer to Sun's official resources for support or additional details
on JSSE 
          configuration.
         </p>
  
          <source><![CDATA[
    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(); 
         }
       }
    }
          ]]></source>
  
      </section>
  
    </body>
  
  </document>
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


Mime
View raw message