It’s been a while, I had any blog post. I have been occupied with other CF stuffs, CF12 PR, CFML Slack and CF customers. And this article has been there in my draft for a while now. So, recently I worked with a lot of CF users having trouble with CFHTTP calls over SSL servers and proxy servers.
The CFHTTP tag attributes are explained at https://wikidocs.adobe.com/wiki/display/coldfusionen/cfhttp. There are a few articles available for CFHTTP setup over SSL & proxy, but they seems to be a bit complicated. I want to keep it simple and straightforward with few steps and verify the usage. So here you go:-
1) Importing Certficate to Java/CF Keystore
- Go to a page on the SSL server in question.
- Double-click the lock icon on browser.
- Click the Details tab.
- Click Copy To File.
- Select the base64 option and save the file.
- Copy the CER file into \ColdFusion11\jre\lib\security\ (or whichever JRE ColdFusion is using). As Charlie suggested, you can verify the JRE location or “Java Virtual Machine Path” inside CF Admin at Server Settings > Java and JVM.
- Run the following command in the same directory (keytool is located at \ColdFusion11\jre\bin\):
keytool -import -alias name -keystore \ColdFusion11\jre\lib\security\cacerts -file mycert.cer
You can also refer to https://www.sslshopper.com/tomcat-ssl-installation-instructions.html.
Note: – While downloading the certificate, please select “DER” (as shown below)
2) Sample Code to Test CFHTTP Functionality
Once you have imported the certs correctly, you can access your application. However, you can also try with a quick sample code (as like, the one mentioned below). If that works, then you can check your application as well.
But before that, please try accessing http://www.w3schools.com/webservices/tempconvert.asmx in browser, from the same server. We need to ensure this first.
Run the below sample code snippet.
<cfsavecontent variable="localscope.soapRequest">
<cfoutput>
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<CelsiusToFahrenheit xmlns="http://www.w3schools.com/webservices/">
<Celsius>10</Celsius>
</CelsiusToFahrenheit>
</soap:Body>
</soap:Envelope>
</cfoutput>
</cfsavecontent>
<cfhttp method="POST" url="http://www.w3schools.com/webservices/tempconvert.asmx" proxyServer="127.0.0.1" proxyPort="8080" proxyUser="MyUser" proxyPassword="MyPassword" resolveurl="NO" result="httpResponse">
<cfhttpparam type="xml" name="body" value="#localscope.soapRequest.Trim()#">
<cfhttpparam type="header" name="Connection" value="keep-alive" >
<cfhttpparam type="header" name="SOAPAction" value="http://www.w3schools.com/webservices/CelsiusToFahrenheit" >
<cfhttpparam type="header" name="Content-Type" value="text/xml; charset=utf-8">
</cfhttp>
<cfdump var="#httpResponse#" label="httpResponse">
You should be getting an output, like the below screenshot:-
A Statuscode 200 confirms the functionality.
In case you are behind a proxy server and not able to hit http://www.w3schools.com/webservices/tempconvert.asmx, then you can try a CFHTTP “GET” call to any web url, which is accessible from your server. It can be http://www.google.com or any intranet/internet url.
Your test code snippet will change to:-
<cfhttp method="GET" url="http://www.google.com" proxyServer="127.0.0.1" proxyPort="8080" proxyUser="MyUser" proxyPassword="MyPassword" resolveurl="NO" result="httpResponse">
</cfhttp>
<cfdump var="#httpResponse#" label="httpResponse">
3) Test Your Application
Once the test code works, you can try your CFHTTP call. Or you can directly execute your code and verify the CFHTTP call. To get the soap:Envelope and Mimetype details, you can use Soap UI such as http://www.soapui.org/.
TROUBLESHOOTING:-
After importing certificates, if you still have issues (even with the sample code snippets), then you need to enable debugging for SSL. Take a backup of jvm.config at \ColdFusion11\cfusion\bin\ and add -Djavax.net.debug=all under the “Arguments to VM” in jvm.config. This would require a CF service restart. The argument would append the debugging info to the coldfusion-out.log at \ColdFusion11\cfusion\logs\.
The most common error is handshake_failure. If you see the same at the bottom of coldfusion-out.log, then please verify that the cert is listed in the same log, with the CF service starts up entry.
If the certificate(s) aren’t there, then please import the certs into the keystore, as per STEP 1 of this article.
If the certificate(s) are there, then add the below arguments in jvm.config with respective values as per your specification and restart CF. You can then, test the Application. This will tell CF to look for the specific truststore and keystore files.
For e.g.:-
-Djavax.net.ssl.keyStore= \ColdFusion11\jre\lib\security\cacerts
-Djavax.net.ssl.keyStorePassword=changeit
-Djavax.net.ssl.trustStore= \ColdFusion11\jre\lib\security\cacerts
-Djavax.net.ssl.trustStorePassword=changeit
Note:- The location mentioned above is the default location. It may vary, if you are using an external JRE. Please refer to Step 6 under “Importing Certficate to Java/CF Keystore“, to verify the JRE location. Thanks Charlie, note taken.
javax.net.ssl.keyStore |
Location of the Java keystore file containing an application process’s own certificate and private key. On Windows, the specified pathname must use forward slashes, /, in place of backslashes, \. |
javax.net.ssl.keyStorePassword |
Password to access the private key from the keystore file specified by javax.net.ssl.keyStore. This password is used twice:
- To unlock the keystore file (store password), and
- To decrypt the private key stored in the keystore (key password).
In other words, the JSSE framework requires these passwords to be identical. |
This is applicable to both ColdFusion 10 and ColdFusion 11.