ColdFusion Login Wizard Extension
ColdFusion MX 7 includes several powerful extensions for Dreamweaver that enhance ColdFusion development. One of these is the new Login Wizard. The Login Wizard allows developers to quickly create login forms and well-formed ColdFusion components that leverage the ColdFusion security framework. Developers can either use templates created by the ColdFusion Login Wizard to secure their application directories, or incorporate the code within the templates into the developer's own security paradigms.The ColdFusion installer copies the extension installer (CFMX7DreamWeaverExtensions.mxp) to the CFIDE/installers directory. After double-clicking on the executable, the Macromedia Extension Manager opens and installs the extensions into Dreamweaver.To start the Login Wizard, open Dreamweaver, open the Commands menu and select ColdFusion Login Wizard. Figure 8.26 shows the wizard's Welcome screen. Then follow these steps to create security templates with the Login Wizard:
1. | With the Login Wizard open, click Next. |
2. | On the Specify an Application to Secure page shown in Figure 8.27, select whether to secure a Dreamweaver site or a specific directory. If you choose to secure a specific directory, you can use the Browse utility to select that directory. Click Next.Figure 8.27. Specify either the active Dreamweaver site or a directory to be secured.[View full size image] ![]() Figure 8.28. Verify that you want to add security templates to the existing application directory.[View full size image] ![]() |
3. | The Specify Authentication Type page (Figure 8.29) opens next. Select the type of authentication you want to employ. Then choose whether you want the wizard to create a Browser dialog box or a ColdFusion login page as a user login screen.
Figure 8.29. Specify an authentication type and the type of login form to present the user.[View full size image] ![]() |
4. | Click Next. Your authentication type selection in step 3 determines the next page:If you chose Simple authentication, then you'll see Figure 8.30. Enter a user name and password for user authentication, and click Next.Figure 8.30. Enter a user name and password for simple authentication.[View full size image] ![]() Figure 8.31. Enter the Windows domain to use for authentication.[View full size image] ![]() Figure 8.32. Enter the values necessary to authenticate to the LDAP server.[View full size image] ![]()
Figure 8.33. Enter the query string, in the format of the user's full DN, used to authenticate the user against the LDAP server.[View full size image] ![]() |
5. | Click Next. Then click Done on the Wizard Complete screen (Figure 8.34) to close the wizard.Figure 8.34. The Login Wizard has been successfully completed.[View full size image] ![]() |
Figure 8.26. Welcome to the Dreamweaver ColdFusion Login Wizard.
[View full size image]

- Authentication methods for each authentication type :
Simple (simpleauth), NT Domain (ntauth), and LDAP (ldapauth). These methods validate the submitted user name and password and return whether or not the authentication was successful. All authentication methods are generated. including those not chosen in the wizard. - performLogin method :
This method contains the <cflogin> container that presents the login challenge, calls the appropriate authentication method, and logs the authenticated user in with <cfloginuser>. - Logout method :
Calls <cflogout> and logs out the current user. It also calls the closeBrowser method if Browser Dialog Box was selected as the challenge method in the wizard. The call to closeBrowser prevents the browser from continuing to send old login information after the call to <cflogout>. - closeBrowser :
This method uses JavaScript to prompt the user to close the browser and/or closes the browser to complete the logout process.
mm_wizard_login.cfm. The login form presented to the user if ColdFusion login was chosen in the wizard.index.cfm/mm_wizard_index.cfm. A standard ColdFusion template for testing security without compromising existing applications. If an index.cfm already exists, then only the mm_wizard_index.cfm file is created.tipApplication.cfc overrides any Application.cfm templates in the same directory path. Consider moving your application logic in Application.cfm to the application event handlers in Application.cfc. See the "Migrating from Application.cfm to Application.cfc" section of the chapter, "Designing and Optimizing a ColdFusion Application" in the Developing ColdFusion MX Applications help manual at http://livedocs.macromedia.com/coldfusion/7/htmldocs/00001123.The code generated by the wizard can be used as is for the most part; however, it has some shortcomings that you should customize before putting it into production:
- The Application.cfc contains no initialization variables, including application name, LoginStorage, SessionManagement, SessionTimeout, SetClientCookies, or the like. You should code these variables to strengthen your security paradigm.
- Consider changing the simpleAuth authentication method to perform a database query using the submitted user name and password instead of a simple string comparison. Use the Hash() function to strengthen the security of passwords in the database.
- The authentication methods contain simplified code and may not work without modification. For example, the LDAP code queries for an attribute named "roles", which is probably not valid for most LDAP servers.
- The authentication methods only return Boolean values in ColdFusion structures that indicate whether authentication failed. Modify the code to populate the structure with the authenticated user's roles, as well.
- All authenticated users are granted a single role: user. Modify this hard-coded <cfloginuser> value in the performLogin method to dynamically accept roles returned from the authentication methods.
- The wizard allows you to specify a Browser dialog box, but it does not allow you to specify the authentication realm. Modify the default Basic Realm values in the <cfheader> tag in the performLogin method.
tipChoosing the right login challenge is important. Select Browser Dialog Box if you are integrating with Web server authentication, or chose NT Domain as the authentication type. Use a ColdFusion login page for database and LDAP logins, because a database and LDAP won't be able to validate the Basic Realm of the WWW Authentication header passed by the Browser dialog box.
ColdFusion Login Wizard Example
The following example uses the templates generated by the ColdFusion Login Wizard to perform authentication against a Windows domain. Listing 8.4 shows the mm_wizard_login.cfm, which displays the login form. The Application.cfc in Listing 8.5 has been modified with the coding of the THIS.name variable, to set the application name. The mm_wizard_include.cfm in Listing 8.6 records the parameters entered into the wizard fields and passes them to the mm_wizard_authenticate.cfc. The simpleauth and ldapauth methods have been removed from the mm_wizard_authenticate.cfc in Listing 8.7. The ntauth method has been modified to return the authentication structure returned from the <cfntauthenticate>, which is used to log in the user.Table 8.6 lists the <cfntauthenticate> attributes; Table 8.7 lists the fields in the returned structure.
ATTRIBUTE | DESCRIPTION | REQUIRED |
---|---|---|
username | A username to authenticate against the specified domain. | Yes |
password | The password for the specified username. | Yes |
domain | Windows domain to authenticate against. ColdFusion must be running on a server within the specified domain. | Yes |
result | Variable name for the return structure. Default value is cfntauthenticate. | No |
listGroups | Boolean indicating whether or not to return the domain groups to which the authenticated user belongs. Default value is no. | No. |
FIELD | DESCRIPTION |
---|---|
auth | Boolean indicating whether the user is authenticated. |
groups | Comma-delimited list of groups in the specified domain to which the user belongs. This field is only returned if the ListGroups=yes. |
name | The same value as the username attribute. |
status | Authentication status. Returns one of the following: success means the username is found in the domain and the password is valid; UserNotInDirFailure means the username is not found in the specified domain; AuthenticationFailure means the username is found, but the password is invalid. |
Listing 8.4. mm_wizard_login.cfm
[View full width]
<cfsetting enablecfoutputonly="yes">
<!---####
File name: mm_wizard_login.cfc
Description: Login form created by the ColdFusion Login Wizard.
Assumptions: None
Author name and e-mail: Sarge (ssargent@macromedia.com)
Date Created: February 22, 2005
####--->
<cfsetting enablecfoutputonly="no">
<cfparam name="errorMessage" default=">
<!--- output error message if it has been defined --->
<cfif len(trim(errorMessage))>
<cfoutput>
<ul>
<li><font color="FF0000">#errorMessage#</font></li>
</ul>
</cfoutput>
</cfif>
<!--- This is the login form, you can change the font and color etc but please keep theusername and password input names the same --->
<cfoutput>
<h2>Please Login using #args.authtype# authentication.</h2>
<cfform name="loginform" action="#CGI.script_name#?#CGI.query_string#" method="Post">
<table>
<tr>
<td>username:</td>
<td><cfinput type="text" name="j_username" required="yes" message="A usernameis required"></td>
</tr>
<tr>
<td>password:</td>
<td><cfinput type="password" name="j_password" required="yes" message="Apassword is required"></td>
</tr>
</table>
<br>
<input type="submit" value="Log In">
</cfform>
</cfoutput>
Listing 8.5. Application.cfc
[View full width]
<!---####
File name: Application.cfc
Description: Template created by the ColdFusion Login Wizard that handles applicationevents.
Assumptions: None
Author name and e-mail: Sarge (ssargent@macromedia.com)
Date Created: February 22, 2005
####--->
<cfcomponent>
<!---#### Application initialization variables. ####--->
<cfset THIS.name = "ows">
<cffunction name = "onRequestStart">
<cfargument name = "thisRequest" required="true"/>
<cfinclude template="mm_wizard_application_include.cfm">
<cfif GetAuthUser() NEQ ">
<cfoutput>
<cfform action="mm_wizard_authenticate.cfc?method=logout&loginType=#args.authLogin#" method="Post">
<cfinput type="submit" name="Logout" value="Logout">
</cfform>
</cfoutput>
</cfif>
</cffunction>
</cfcomponent>
Listing 8.6. mm_wizard_include.cfm
[View full width]
<cfsetting enablecfoutputonly="yes">
<!---####
File name: mm_wizard_application_include.cfm
Description: Template created by ColdFusion Login Wizard that records authenticationinformation from the wizard fields and passes them to the mm_wizard_authenticate.cfc
Assumptions: None
Author name and e-mail: Sarge (ssargent@macromedia.com)
Date Created: February 22, 2005
####--->
<cfsetting enablecfoutputonly="no">
<!--- MM WIZARD CODE: BEGIN --->
<!--- Set the NT Authentication Logic parameters --->
<cfset args = StructNew()>
<!--- Authentication Type ---->
<cfset args.authtype = "NT">
<!--- Domain Name ---->
<cfset args.domain = "Macromedia">
<!--- Login type--->
<cfset args.authLogin = "CFlogin">
<!--- Login Page ---->
<cfset args.loginform = "mm_wizard_login.cfm">
<!--- Call the CFC to perform the authentication --->
<cfinvoke component="mm_wizard_authenticate" method="performlogin">
<cfinvokeargument name="args" value="#args#">
</cfinvoke>
<!--- MM WIZARD CODE: END --->
Listing 8.7. mm_wizard_authenticate.cfc
[View full width]
<!---####
File name: mm_wizard_authenticate.cfc
Description: Modified ColdFusion Login Wizard template that performs user authenticationand login.
Assumptions: This template only performs Windows authentication -- all otherauthentication methods are removed.
Author name and e-mail: Sarge (ssargent@macromedia.com)
Date Created: February 22, 2005
####--->
<cfcomponent>
<!---- ////////////////////////////////////////////////////--->
<!---- NT Domain Authentication --->
<!---- ////////////////////////////////////////////////////--->
<cffunction name="ntauth" access="private" output="false" returntype="struct"hint="Authenticate against a NT domain">
<cfargument name="nusername" required="true" hint="The username">
<cfargument name="npassword" required="true" hint="The password">
<cfargument name="ndomain" required="true" hint="The domain to authenticate against">
<!---#### Modify the <cfntauthenticate> by setting listgroups=yes ####--->
<cfntauthenticate
username="#arguments.nusername#"
password="#arguments.npassword#"
domain="#arguments.ndomain#"
result="authenticated"
listgroups="yes">
<cfreturn authenticated>
</cffunction>
<!---- ////////////////////////////////////////////////////--->
<!--- This method performs the <cflogin> call and in turn --->
<!--- calls the actual authentication method --->
<!---- ////////////////////////////////////////////////////--->
<cffunction name="performlogin" access="public" output="true" hint="Log a user in usingeither NT authentication.">
<cfargument name="args" type="struct" required="true" hint="These are the parameterssetup by the Login Wizard">
<cflogin>
<cfif NOT IsDefined("cflogin")>
<cfinclude template="#args.loginform#"><cfabort>
<cfelse>
<cftry>
<cfinvoke method="ntauth"
returnvariable="result"
nusername="#cflogin.name#"
npassword="#cflogin.password#"
ndomain="#args.domain#" >
<cfcatch>
<cfset errorMessage = "Your login information is not valid.<br>Please Try again">
<cfinclude template="#args.loginform#"><cfabort>
</cfcatch>
</cftry>
</cfif>
<!--- validate if the user is authenticated --->
<cfif result.auth eq "YES">
<!--- if authenticated --->
<cfloginuser name="#cflogin.name#" password="#cflogin.password#" roles="#result.groups#">
<cfelse>
<!--- if not authenticated, return to login form with an error message --->
<cfset errorMessage = "Your login information is not valid.<br>Please Try again">
<cfinclude template="#args.loginform#"><cfabort>
</cfif>
</cflogin>
</cffunction>
<!---- ////////////////////////////////////////////////////--->
<!--- Logout --->
<!---- ////////////////////////////////////////////////////--->
<cffunction name="logout" access="remote" output="true" hint="Log the user out.">
<cfargument name="logintype" type="string" required="yes" hint="The login type used tologin.">
<cfif isDefined("form.logout")>
<cflogout>
<cfif arguments.logintype eq "challenge">
<cfset foo = closeBrowser()>
<cfelse>
<!--- replace this URL to a page logged out users should see --->
<cflocation url="http://www.macromedia.com">
</cfif>
</cfif>
</cffunction>
<!---- ////////////////////////////////////////////////////--->
<!--- Close Browser --->
<!--- To ensure the header authentication information --->
<!--- has been thouroughly flushed the browser should be closed --->
<!---- ////////////////////////////////////////////////////--->
<cffunction name="closeBrowser" access="public" output="true" hint="Close the browser toclear the header information.">
<script language="javascript">
if(navigator.appName == "Microsoft Internet Explorer") {
alert("The browser will now close to complete the logout.");
window.close();
}
if(navigator.appName == "Netscape") {
alert("To complete the logout you must close this browser.");
}
</script>
</cffunction>
</cfcomponent>