Note: [Mar 23, 2017] This website was migrated to a new platform recently. Some linked content may not be accessible until all the links are configured properly,

Java client connecting to an https resource via a proxy server that needs authentication

Submitted by Kamal Wickramanayake on July 9, 2010 - 18:20

This doesn't look to be something trivial that you can simply do by passing the URL, proxy server host, port, user name and password to an already available class and getting the connection established.

Can you use the HttpURLConnection?

Even though you can set the https.proxyHost and https.proxyPort system properties [e.g. System.setProperty(“https.proxyHost”, “myhost”) ], sending the user name and passwords to the proxy server using an HttpURLConnection instance is not possible directly (see the bottom of this page for a solution). This is because the class assumes that all the HTTP headers that you may set using the setRequestProperty() method are meant to be sent over the encrypted channel to the target server, but not the proxy server. Hence, you cannot set a “Proxy-Authorization” header targeting the proxy server.

Solution

You can use the following steps to connect to an https resource via a proxy server that requires authentication:

  1. Create a plain socket to the proxy server.
  2. Write to the proxy server an HTTP CONNECT request. HTTP CONNECT request will include the target server and port. Make sure that this HTTP request header also includes the base64 encoded proxy server user name and password (i.e. the “Proxy-Authorization” header).
  3. If the CONNECT request was successful, you are now connected to the target server. Now you need to do SSL handshaking using the same socket.
  4. Get an instance of the SSLSocketFactory [You can use the SSLSocketFactory.getDefault() method].
  5. Use the createSocket() method of SSLSocketFactory to get an SSLSocket by passing the already available socket as a parameter (with other parameters).
  6. Of the new SSLSocket you created, invoke the startHandshake() method.
  7. Now you are done. You have an encrypted channel to the target server.

If you wish, you can then go about writing the HTTP headers to the target server over the so created encryption channel. For example, you may generate a GET request.

Java SSL through authenticated proxy

Yet another neat approach as seen above is to pack the above  code into a class that subclasses the SSLSockertFactory. You can then go about passing an instance of this class to the HttpsURLConnection class's setSSLSocketFactory() method. There you will first create a URL, invoke the openConnection() method, set the SSLSocketFactory of the returned HttpsURLConnection instance and then go about using the io capabilities. In case you are interested in coding all these, look at http://www.javaworld.com/javaworld/javatips/jw-javatip111.html?page=1