OpenID And ColdFusion

Recently I wanted to investigate building an OpenID identity provider in ColdFusion. While there are a few OpenID consumer libraries out there, I didn't really find any ColdFusion implementations for an OpenID server. Plus, given that OpenID is an authentication protocol there are heightened security considerations, so I wanted something that was well tested and widely used. This lead me to the OpenID4Java project. Looking at the documentation and source for the project there appeared to be pretty straight forward implementations for both an OpenID provider and consumer via the ServerManager and ConsumerManager classes so I began to port the sample JSP applications over to ColdFusion. That is were my problems began.

At first I tried loading the library and its dependencies via JavaLoader, but I kept getting strange security errors. Thinking it may have something to do with JavaLoader I tried putting the libraries on ColdFusion's class path but continued to get the same security errors. After much trail and error I finally found the source of the problem, the RSA BSafe Crypto-J security provider used by Enterprise editions of ColdFusion, including the Developer edition of ColdFusion. It turns out the RSA library, while providing FIPS 140 compliance, has some issues that break OpenID4Java. The core of the problem can be illustrated with the following code:

<cfscript>
keyGen = CreateObject("java","javax.crypto.KeyGenerator").getInstance('HmacSHA1');
keyGen.init(160);
key = keyGen.generateKey();
WriteOutput(key.getAlgorithm());
</cfscript>

You will notice that we use the HmacSHA1 algorithm to generate a key, however if you run the code you will find that when we call getAlgorithm() on that key it returns "HMAC". Unfortunately "HMAC" is not a standard algorithm name, and thus causes problems with OpenID4Java. Once I figured this out I went on to discover two solutions which I'll detail below.

Solution One: Disabe the RSA Libraries

It turns out that the RSA BSafe Crypto-J library can be disable via arguments to the JVM. To disable the RSA libraries simply append the following entry in java.args: -Dcoldfusion.disablejsafe = true. (The java arguments can be updated directly in the jvm.config file. This file is located in ColdFusion{version}/runtime/bin for ColdFusion server installations or in JRun4/bin for multiserver installations.) In my case I was going to be running on a shared server so changing the JVM config wasn't option. On to solution two.

Solution Two: Modify OpenID4Java to Explicitly use the SunJCE Security Provider

The sample above can be "fixed" if we modify the code to explicitly use the SunJCE security provider.

<cfscript>
keyGen = CreateObject("java","javax.crypto.KeyGenerator").getInstance('HmacSHA1','SunJCE');
keyGen.init(160);
key = keyGen.generateKey();
WriteOutput(key.getAlgorithm());
</cfscript>

Running the above snippet we get "HmacSHA1" which is what OpenID4Java needs to work correctly. Given this I downloaded the OpenID4Java source code and made this modification where necessary. With this simple modification in place I was able to compile and package the OpenID4Java library and use it to build a basic OpenID server for ColdFusion.

OpenID4CF

For anyone else interested in using OpenID4Java on ColdFusion I've package up my modified version and made it available on RIAForge as OpenID4CF. The download contains two libraries: version 0.9.5 of OpenID4Java library (openid4java.jar), modified to explicitly use the Sun JCE security provider, and version 1.9.14 of the CyberNeko HTML Parser (nekohtml.jar). These should be the only libraries you need to get up and running with OpenID4Java on ColdFusion. The RIAForge SVN repo for OpenID4CF also has simple consumer and provider applications, built using FW/1 and JavaLoader.

One final note, if you are using the Standard version of ColdFusion I don't believe it uses the RSA libraries, in which case you should be able to use OpenID4CF without any modifications to your ColdFusion configuration or the OpenID4Java library.

Comments
Wil Genovese's Gravatar Have you seen/tried OpenID Server for ColdFusion? I'm curious because I've been researching setting up OpenID also. I'm experimenting with the ColdFusion based OpenIDServer that is at RIAForge.org or at http://www.yakhnov.info/go/projects/openid/.

The OpenID Foundation website lists this as one of the possible servers to use.

http://openid.net/developers/libraries

So far it seems like a pretty good ColdFusion based OpenID server. I'm still experimenting with integrating OpenID into our applications but I think we may use this. I'm wondering how this compares to OpenID4Java.
# Posted By Wil Genovese | 4/16/10 2:13 PM
Nathan Mische's Gravatar I did take a look at OpenIDServer, but I seem to recall it only supported OpenID 1.1 and didn't support extensions such as Attribute Exchange or Simple Registration. (I could be wrong here.)

OpenID4Java supports OpenID 2.0 and extensions. Plus it was originally developed by Sxip, one of the major drivers of the OpenID spec. (If you look the main OpenID4Java author, Johnny Bufu, is listed as a contributor to most of the OpenID specs.) Another factor is that OpenID4Java is used and maintained by some pretty big organizations. For example I know Atlassian uses it and has contributed to the project. I'm not really sure how many people are using OpenIDServer or how well it is maintained.
# Posted By Nathan Mische | 4/16/10 2:58 PM
Dom's Gravatar Thanks for blogging this - this helped me diagnose my CFHTTP connection failure issue. I fixed with the following in onApplicationStart()

<cfset objSecurity = createObject("java", "java.security.Security") />
<cfset objSecurity.removeProvider("JsafeJCE") />
# Posted By Dom | 6/27/12 12:46 PM
BlogCFC was created by Raymond Camden. This blog is running version 5.8.001.