Add Spring Security to ColdFusion

by

We are evaluating Spring Security as a part of our authentication and authorization platform. Since we have many ColdFusion apps, it was natural for us to see how it would work in tandem with ColdFusion. Fortunately, since ColdFusion is a Java web application, Spring Security fits right in.

In this post, I’ll show the basics of connecting Spring Security with ColdFusion. I’m not intending to teach how Spring Security works or other details of implementation. For more information, see the Spring Security Reference Documentation (also available as a PDF).

At a high level, you add Spring Security as a Servlet Filter that is setup to run before the ColdFusion servlet in the Java web application config file (web.xml). To make it as easy as possible to see how it works, I’ll show you how to to setup the Spring Security tutorial app. I’m starting with a new install of ColdFusion 9.0.1, installed as a J2EE app under Tomcat 6.0.29 (running on JDK 1.6.0.22, 64-bit on Windows XP Pro).

  1. Download Spring Security from here (using version 3.0.5, the latest as of this writing).
  2. Extract the zip file (spring-security-3.0.5.RELEASE.zip).
  3. Extract the tutorial WAR file located in
    spring-security-3.0.5.RELEASE/dist/spring-security-samples-tutorial-3.0.5.RELEASE.war
    to a local directory (I’ll call it <tutorial-war>).NOTE: If you’ve never run the Spring Security tutorial, you can just put the <tutorial-war> directory into the /webapps directory of your Tomcat app server and run it. Here is more info about Spring Security tutorial.
  4. Copy all of the .jar files from:
    <tutorial-war>/WEB-INF/lib
    into:
    <cf-app>/WEB-INF/lib
  5. Copy the file:
    <tutorial-war>/WEB-INF/classes/log4j.properties
    to:
    <cf-app>/WEB-INF/classes/log4j.properties
  6. Copy the file:
    <tutorial-war>/WEB-INF/applicationContext-security.xml
    to:
    <cf-app>/WEB-INF/applicationContext-security.xml
  7. Copy indicated lines from:
    <tutorial-war>/WEB-INF/web.xml
    to:
    <cf-app>/WEB-INF/web.xml 

    1. Under the line:
      <description>Adobe ColdFusion 9</description>
      (line 5 in my stock CF9 web.xml), insert the <context-param /> blocks from
      <tutorial-war>/WEB-INF/web.xml
      (NOTE: In the code below, I removed the first line in the first <context-param /> from the tutorial that said
      classpath:applicationContext-business.xml.):

      	<!-- INSERTED FOR SPRING SECURITY -->
      
          <!--
            - Location of the XML file that defines the root application context
            - Applied by ContextLoaderListener.
            -->
          <context-param>
              <param-name>contextConfigLocation</param-name>
              <param-value>
      			<!-- REMOVED classpath:applicationContext-business.xml -->
                  /WEB-INF/applicationContext-security.xml
              </param-value>
          </context-param>
      
          <context-param>
              <param-name>log4jConfigLocation</param-name>
              <param-value>/WEB-INF/classes/log4j.properties</param-value>
          </context-param>
      
          <context-param>
              <param-name>webAppRootKey</param-name>
              <param-value>tutorial.root</param-value>
          </context-param>
      
      	<!-- END INSERT FOR SPRING SECURITY -->
      
    2. Under the many <context-param /> blocks and before the <filter /> blocks (around line 64 in my stock CF9 web.xml), insert:
      	<!-- INSERTED FOR SPRING SECURITY -->
      
          <filter>
              <filter-name>springSecurityFilterChain</filter-name>
              <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
          </filter>
      
          <filter-mapping>
            <filter-name>springSecurityFilterChain</filter-name>
            <url-pattern>/*</url-pattern>
          </filter-mapping>
      
      	<!-- END INSERT FOR SPRING SECURITY -->
      
    3. Under the <filter-mapping /> blocks and before the <listener /> blocks (around line 167 in my stock CF9 web.xml), insert:
      	<!-- INSERTED FOR SPRING SECURITY -->
      
          <listener>
              <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
          </listener>
      
          <listener>
            <listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class>
          </listener>
      
          <listener>
              <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
          </listener>
      
      	<!-- END INSERT FOR SPRING SECURITY -->
      
  8. Now, we have to adjust ColdFusion’s logging configuration so that Spring Security’s configuration and libraries are favored.
    1. Rename the file:
      <cfapp>/WEB-INF/cfusion/lib/commons-logging-1.1.1.jar
      to:
      <cfapp>/WEB-INF/cfusion/lib/commons-logging-1.1.1.jar.bak
    2. Rename the file:
      <cfapp>/WEB-INF/cfusion/lib/commons-logging-api-1.1.1.jar
      to:
      <cfapp>/WEB-INF/cfusion/lib/commons-logging-api-1.1.1.jar.bak
    3. Rename the file:
      <cfapp>/WEB-INF/cfform/jars/commons-logging.jar
      to:
      <cfapp>/WEB-INF/cfform/jars/commons-logging.jar.bak
    4. Rename the file:
      <cfapp>/WEB-INF/cfform/jars/commons-logging.properties
      to:
      <cfapp>/WEB-INF/cfform/jars/commons-logging.properties.bak
    5. Create the file:
      <cfapp>/WEB-INF/classes/commons-logging.properties
      , and insert the following into it:

      	org.apache.commons.logging.LogFactory=org.apache.commons.logging.impl.SLF4JLogFactory
      	org.apache.commons.logging.Log=org.apache.commons.logging.impl.Log4JLogger
      
  9. Extract the file security.tld from the META-INF directory of the file
    <cfapp>/WEB-INF/lib/spring-security-taglibs-3.0.5.RELEASE.jar
    and put it into the
    <cfapp>/WEB-INF/lib
  10. Edit the file:
    <cf-app>/WEB-INF/applicationContext-security.xml
    and comment out the <session-management /> block (around line 35), like so:

    	<!--
    	<session-management invalid-session-url="/timeout.jsp">
    		<concurrency-control max-sessions="1" error-if-maximum-exceeded="true" />
    	</session-management>
    	-->
    
  11. That should be all of the server-side configuration you need to make Spring Security work with ColdFusion. When you startup your app server, you should see a lot of Spring Security related output in your console, ending with:

    Root WebApplicationContext: initialization completed in  ms

    Since you can use JSP Tag Libraries in ColdFusion templates or CFCs, you can import Spring Security’s taglib and then easily restrict access to certain content or code using Spring Security’s access expressions. Here’s an example CFM file.

    <cfimport taglib="/WEB-INF/lib/security.tld" prefix="security">
    <html>
    <head>
    	<title>Spring Security on ColdFusion tester</title>
    </head>
    <body>
    	<h1>Spring Security on ColdFusion Test Application</h1>
    	<cfinclude template="/include/nav.cfm" />
    
    	<security:authorize access="isAuthenticated()">
    	<p>You can see this because you are authenticated.</p>
    	</security:authorize>
    
    	<security:authorize access="hasRole('ROLE_SUPERVISOR')">
    	<p>You can see this because you have supervisor permission.</p>
    	</security:authorize>
    
    </body>
    </html>
    

    That’s just the beginning — but a pretty strong beginning that opens up a whole new world of enterprise-class security.

Advertisements

4 Responses to “Add Spring Security to ColdFusion”

  1. jonwolski Says:

    Mmmm…Java. It makes everything better. This is pretty cool stuff. I had used servlet filters with Coldfusion before, but I didn’t know you could utilize JSP taglibs. The two together make this sit along side CFML quite nicely.

  2. Kai Tischler Says:

    Hello Dug !

    A Google Search for “ColdFusion Security” has led me to Your blog thread. It looks like an extraordinary detailed and thorough description of the integration procedure …

    I have some questions in April 2011:
    – I guess You have had some experiences with the “ColdFusion 9.0.1 + Spring Security 3.0.5” couple in the meantime; do You (still) recommend this security approach ?

    – Do You have an UI for management of users, groups and permissions ? Or how do You do that with Spring Security ?

    – The ColdFusion 9.0.1 installation:
    – I have the server one; leveraging JRUN and the builtin web server; do You have a recipe for this installation, too ?
    – Or should I choose the J2EE app installation ?

    – Which (ColdFusion) Web Framework do You use/recommend ?

    TIA for Your reply (comment) !

    Cheers and Tschüss

    Kai (Tischler) from Northrhine-Westfalia in Germany

    P.S.: That I’ve sent this comment on April Fool’s Day is only a coincidence … I suppose Your ColdFusion security approach could be a valid and good choice …

  3. Kai Tischler Says:

    One crucial question I have forgotten to ask: What about (Shared) Hosting ? Before using this involved multi-step integration procedure, I would like to know: Is this approach compliant with (Shared) Hosting ? That is are there any Hosting Providers – Adobe ColdFusion; Railo; (Open) BlueDragon; Cloud; WhatHaveYou – who offer the realization of this Spring Security Integration Approach ?

  4. Baci Says:

    Thanks for this! Having just completed Spring Framework Core Spring training, I’m ready to have at this. One question. Our vendor provided environment (Liferay, CAS) already uses the Spring Framework. instead of deploying it again, I’d like to use it as deployed (and already sharing a security context) These instruction are a fresh install of the framework. How might I go about utilizing the security context of the existing Spring implementation in our CF deployment (portlets)? Thanks in advance for any ideas you might have.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


%d bloggers like this: