One of the end points that we query was suddenly changed from HTTP and HTTPS using a self signed cert and invalid host name in the cert. Sadly you can't just change the URL in your config file and everything works. What I needed to do was to change my querySOAP function to work for both HTTP and HTTPS. Here's what I came up with.Oh and this function also supports HTTP authentication. Nice!
public static String querySoap(String url, String soapAction, String msg, final String username, final String password) {
String ret = null;
try {
boolean HTTPS = false;
if( url.substring(0, 5).equalsIgnoreCase("https") ) HTTPS = true;
Config c = new Config();
Log.log(Level.INFO, "Url: " + url
+ "\r\nSoapAction: " + soapAction
+ "\r\nSoapMessage: " + msg);
URLConnection connection;
URL u = new URL(url);
if( HTTPS ) {
Log.log(Level.INFO, "We use SSL to connect to : " + url);
// Create a trust manager that does not validate certificate chains
TrustManager[] trustAllCerts = new TrustManager[] {new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(X509Certificate[] certs, String authType) {
}
public void checkServerTrusted(X509Certificate[] certs, String authType) {
}
}
};
// Install the all-trusting trust manager
try {
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
} catch (Exception e) {
}
// Create all-trusting host name verifier
HostnameVerifier allHostsValid = new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) {
return true;
}
};
// Install the all-trusting host verifier
HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
} else {
Log.log(Level.INFO, "We do not use SSL to connect to : " + url);
}
connection = u.openConnection();
connection.setConnectTimeout(c.httpConTimeout);
connection.setReadTimeout(c.httpConReadTimeout);
connection.setDoOutput(true);
connection.setDoInput(true);
connection.setUseCaches(false);
connection.setRequestProperty("Content-Type","text/xml;charset=UTF-8");
connection.setRequestProperty("SOAPAction", soapAction);
connection.setRequestProperty("User-Agent","Jakarta Commons-HttpClient/3.1");
connection.setRequestProperty("Content-Length","" + msg.length());
if( username != null && password != null) {
String login = username + ":" + password;
String encodedLogin = Base64.encodeBytes(login.getBytes());
connection.setRequestProperty("Authorization", "Basic " + encodedLogin);
}
OutputStream out = connection.getOutputStream();
Writer wout = new OutputStreamWriter(out);
wout.write(msg);
wout.flush();
wout.close();
StringBuffer strBuf = new StringBuffer();
String inputLine;
BufferedReader bufRead = new BufferedReader(new InputStreamReader(connection.getInputStream(),"UTF-8"));
while ((inputLine = bufRead.readLine()) != null) {
strBuf.append(inputLine);
}
bufRead.close();
ret = strBuf.toString();
Log.log(Level.INFO, "SoapResponse: " + ret);
} catch (Exception e) {
e.printStackTrace();
}
return ret;
}
Reference:
http://www.nakov.com/blog/2009/07/16/disable-certificate-validation-in-java-ssl-connections/