HTTPS Connection Through A Proxy Server
843811Jun 19 2003 — edited Oct 9 2007After much reading and a day of messing around I finally stumbled on a configuration that works
when wanting to connect to a https site through a proxy server. Hope someone finds it usefull as this whole area seems very poorly documented. Please post any improvements to the below. Note you'll need to download a Base64Converter class.
import com.sun.net.ssl.*;
import Base64Converter;
import java.net.*;
import java.io.*;
import java.util.*;
/**
* The following code demonstrates how you can connect using HTTPS through a proxy server
* @author richard.durley@eds.com
*/
public static void testHttpsTunnelledThroughProxy()
{
HttpsURLConnection con = null;
BufferedReader reader = null;
InputStream in = null;
String inLine = null;
try
{
//does not seem to matter if you set this or not !
System.getProperties().put( "proxySet", "true" );
//Define the https proxy server and port if your using https connections
System.getProperties().put( "https.proxyHost", "xxx.xxx.xxx.xxx" );
System.getProperties().put( "https.proxyPort", "443" );
//The properties to define the proxy user and password dont seem to work
//you will need to add the Proxy-Authorization header manually to the request
//see futher down
System.getProperties().put("https.proxyUser", "userid");
System.getProperties().put("https.proxyPassword", "password");*/
//Add the route to your cacerts filestore (or a filestore of your choice)
//you'll find ca certs at java_home$/jre/lib/security
//Seems that if you dont add this java will not always find the certificate required for to trust
//the SSL connection.
//
//Note if you still get a CertificateException "could not find trusted
//certificate" then you will need to import the public certificate of the website you are connecting
//to into the keystore using keytool -import -keystore cacerts -file thecert.cer -alias thecertname
//you'll be promoted to enter a password it is 'changeit' by default.
System.setProperty("javax.net.ssl.trustStore", "d:/j2sdk1.4.1_02/jre/lib/security/cacerts");
//Defines the internal ssl protocol implementation
System.setProperty("java.protocol.handler.pkgs","com.sun.net.ssl.internal.www.protocol");
//Adds the ssl provider
java.security.Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
//Define the url you want to connect to, note the name of the host in the certificate needs to match the host in the URL
URL url = new URL("https://www.mysecurehost.com/mysecurepage.html");
System.out.println(url.toExternalForm());
//Open the https URL connection
con = (HttpsURLConnection) url.openConnection();
//Follow redirects if necessary
con.setFollowRedirects(true);
//Set the Proxy-Authorization header for basic proxy authorization
//If you dont do this you will get
//'Unable to tunnel through proxy. Proxy returns "HTTP/1.0 407 Authenticate required' IOException
//You also will need a base64 encoder to encode the userid and password string
con.setRequestProperty( "Proxy-Authorization", "Basic " + Base64Converter.encode("proxyuserid:proxypassword"));
//get the input stream
in = con.getInputStream();
reader = new BufferedReader(new InputStreamReader(in));
inLine = reader.readLine();
//read all lines
while (inLine != null)
{
System.out.println(inLine);
inLine = reader.readLine();
}
//read the cookie string if you want to store it (especially useful to capture the
//session id if returned from the server you can then add this to future requests
String cookie = con.getHeaderField("Set-Cookie");
int index = cookie.indexOf(";");
if(index >= 0) cookie = cookie.substring(0, index);
Balance.cookie=cookie;
//close
reader.close();
in.close();
con.disconnect();
}
catch (Exception e)
{
e.printStackTrace(System.out);
}
}