Zachary Loch

Subscribe to Zachary Loch: eMailAlertsEmail Alerts
Get Zachary Loch: homepageHomepage mobileMobile rssRSS facebookFacebook twitterTwitter linkedinLinkedIn

Related Topics: ColdFusion on Ulitzer, Java EE Journal

CFDJ: Article

ColdFusion Developer's Journal: Implementing a Single Sign-On Solution Using CF

Constructing a single sign-on solution for Web applications

There is an evolution that takes place when organizations start to develop Web applications as part of their IT infrastructure. Initially, an application is written for a particular purpose, say a contact management system or an inventory control system.

These systems typically require a facility to log in with a username and password to control access. As time passes, several of these systems will be built across the organization, each in isolation of one another. The problem soon arises where users need to access several of the Web systems, all with different usernames and passwords. The next logical step is to create a Web portal to provide a single point of entry to the Web applications. The Web applications are then moved into the portal so that users can go to one place to access all of their systems. But what do you do with those applications that cannot be moved into your portal, or if you only have a handful of applications and are not ready for a portal? Are you doomed to leave your users stranded on isolated systems? In this article, we'll answer this question as well as explore East Carolina University's evolution, why some systems cannot be moved into a portal, how to provide a single sign-on solution for those systems, and speak more about the benefits of tackling the problem.

During the development and evolution of the East Carolina University's Onestop ColdFusion-based campus portal, we definitely encountered these issues. As addressed in our article the April 2005 edition of the CFDJ, one of our primary objects was to offer a software development environment managed by the "portal," meaning we wanted to free resources by allowing software development staff to focus on the task at hand rather than all the supporting software. We all know the amount of time spent by development staff creating a security structure, identifying the customer, creating repetitive page layouts, and display elements, etc. By using a development API, we were able to remove these time-consuming processes and allow software developers to simply focus on the software to be developed. If a process was not made available via the API, it was extensible enough to allow development staff to simply build upon the model and offer additional functionality. All was well in campus portal land.

However, while we all lived happily ever after for some time, two major events caused us to recognize and examine a major, missing element within the model. First, we were in the process of refining our portal software to become a marketable product (pssst... anyone need a portal?). Second, our campus had purchased a large, packaged software product from a well-known vendor to address the needs of the entire enterprise. Every process was to be changed in nearly every area of campus business including Human Resources, Finance, and Student, and in all the custom-written legacy software as well as a large amount of the custom "Web" software.

While we knew ColdFusion and our campus portal would definitely be able to address the software development needs of the campus, how were we going to interface with the Web-based applications provided by the new enterprise system? Furthermore, if we are to market a portal product, shouldn't we offer a method of interface to Web-based systems external to our portal? Again, we knew we had a strong product for managing all these resources in a comprehensive, secure environment and would definitely be able to manage applications developed and written specifically for our portal, but how would we manage these external applications and systems? Could we just "pull" or consume these applications directly into our Web portal?

There are several reasons why you might not be able to pull all applications into your Web portal. One reason is that an application might be in a hosted environment. Or perhaps it is a system that was purchased and the code cannot be modified (as in our case), or the system is written in another language. No matter what the reason, it can be frustrating for users to enter separate usernames and passwords for each system in which they need to access. After all, isn't part of the purpose and power of a portal to offer improved and consolidated services to the customer? Of course, but how can we accomplish this goal? Let's look at how we can create a single sign-on solution so that users can stop writing down their passwords and putting them under their keyboards (IT security departments everywhere can breathe easier).

If we take a step back for a second and think about what needs to be accomplished, the problem is straightforward. We would like to present the user with a link from within one application, or portal, into another Web application so that when the link is clicked, a new window opens to the new application and the user is already logged in. If we think about this operation from the browser point of view, it's a simple process. The browser calls a page, which we'll refer to as login.cfm hereafter, and an HTML form is returned. The user then enters the username and password through the browser, hits submit, and the form is sent to the action page specified on the HTML form's action attribute. Usually some cookies are set (we'll discuss this later) and a page is returned to the user. To provide a single sign-on solution, we need to mimic the Web browser process above through code effective at creating a "soft browser." Next, we'll break down each part of the process and see how we can construct a full single sign-on solution with ColdFusion.

Before we dig into coding, some investigative work needs to be done. Let's grab our magnifying glass and don our Sherlock Holmes hat. We need to gather the following information: the URL of the login page, the HTML form element names for the username and password, the URL of the action attribute in the form of the login page, and the URL of the page that is called upon successful login. We can gather this information by having an actual user log into the system and by viewing the HTML source code (most browsers have this option) of each page. After we have gathered the necessary information, we are ready to put our coding hat back on (you do have one...right?).

As we all know, ColdFusion provides some powerful tools to accommodate this process. We could start by sending a <CFHTTP> post request with the username and password to the action page, but most systems set the cookies for authentication up front (for example, CFID, CFTOKEN, JSESSIONID) when you visit the login page. Then, after successful logon, a session variable is set flagging the user as logged in. With that being the case, we need to follow the exact process of the browser. We need to issue a <CFHTTP> request to login.cfm.

<cfhttp method="get" url="">

The server will then send back cookie information, which we need to store in an array or structure so that it can be sent for later HTTP (or HTTPS) requests. ColdFusion makes this extremely easy since the CFHTTP variable holds a nice data structure of all HTTP responses. You can access the structure with cookie information directly by performing the following: <cfset cookieStruct ="#cfhttp.responseheader['Set-Cookie']#">. The "Set-Cookie" structure creates the key names in numeric order (1,2,3) so we need to create a new structure with the key names equal to the cookie names and copy over the values as below:

<!--- pick out cookie information and store in temporary structure--->
<cfset tempCookieStruct ="#cfhttp.responseheader['Set-Cookie']#">

<!--- loop through cookie structure and reformat into new structure with cookie
name as key and cookie value as key value--->
<cfset cookieStruct=StructNew()>
<cfloop collection="#tempCookieStruct#" item="key">
   <cfset cookieKeyAndValue=ListGetAt(tempcookieStruct[key],1,';')>
   <cfset cookieKey=ListGetAt(cookieKeyAndValue,1,'=')>
   <cfset cookieValue=ListGetAt(cookieKeyAndValue,2,'=')>
   <cfset StructInsert(cookieStruct,cookieKey,cookieValue)>

More Stories By Steven Forehand

Steven Forehand is the team manager for the New Technologies Development Group, a team of twelve talented application developers at East Carolina University located in Greenville, North Carolina. He has been using Macromedia ColdFusion since just prior to version 2 and has over nine years of software development experience and is Macromedia ColdFusion MX certified

More Stories By Zachary Loch

Zachary Loch, a Macromedia Certified Advanced ColdFusion MX Developer, is project manager of application development at East Carolina University and also works on special data integration projects. He has 8 years of software development experience in a diverse set of industries including healthcare, insurance, education, and telecommunications.

Comments (3) View Comments

Share your thoughts on this story.

Add your comment
You must be signed in to add a comment. Sign-in | Register

In accordance with our Comment Policy, we encourage comments that are on topic, relevant and to-the-point. We will remove comments that include profanity, personal attacks, racial slurs, threats of violence, or other inappropriate material that violates our Terms and Conditions, and will block users who make repeated violations. We ask all readers to expect diversity of opinion and to treat one another with dignity and respect.

Most Recent Comments
Casey Priest 11/18/05 12:07:02 PM EST

I receive this error when trying to use the code:

Element Set-Cookie is undefined in a CFML structure referenced as part of an expression.

I really need this work - any ideas?

CFDJ News Desk 10/19/05 09:42:09 AM EDT

Implementing a Single Sign-On Solution Using CF. There is an evolution that takes place when organizations start to develop Web applications as part of their IT infrastructure. Initially, an application is written for a particular purpose, say a contact management system or an inventory control system.

INGR8 10/19/05 09:14:45 AM EDT

|| The obvious drawback to this approach is that you must have permission or access to set the setCookies.html file on the target domain ||

Good point.