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.
If an Application.cfc or Application.cfm already exists in the specified site or directory, the wizard will display the confirmation screen shown in Figure 8.28. Click OK to close the confirmation screen. Figure 8.28. Verify that you want to add security templates to the existing application directory. Click Continue to move ahead in the Wizard. | 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. The Simple option provides a standard challenge for a single user name and password. Choose this option for a simple security test and/or to provide a template for a database user name/password challenge. The NT Domain option allows you to specify a single Windows domain for authenticating users. With the LDAP option, you specify properties for authenticating users against an LDAP serverincluding Active Directory. Figure 8.29. Specify an authentication type and the type of login form to present the user.
| 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. If you chose NT Domain authentication, you'll see Figure 8.31. Enter the Windows domain to use for user authentication, and click Next. Figure 8.31. Enter the Windows domain to use for authentication.
If you chose LDAP authentication, you'll see Figure 8.32. Enter the LDAP server information and proper bind DN for an administrative user. Click Verify LDAP Server. If successful, the Next button will become available and you can continue with this step 4; if unsuccessful, modify the information in one or more of the fields and then reverify. Figure 8.32. Enter the values necessary to authenticate to the LDAP server.
tip The wizard will not let you continue until you successfully verify your LDAP settings. The typical causes of failure are an improper Start String, Username, or Password. View your LDAP server logs (if available) to help you debug the bind attempts made during verification. When you're ready, click Next. You'll see the LDAP Authentication Query String page (Figure 8.33). Enter the query string format used to authenticate the user. The query string format should be similar to cn={username},ou=People,dc=company,dc=com. 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.
ColdFusion will substitute the {username} portion of the supplied query string format with the user name submitted in the form. This allows users to enter a simple user name rather than their full DN. | 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.
| Figure 8.26. Welcome to the Dreamweaver ColdFusion Login Wizard.
The Login Wizard creates five ColdFusion templates and a readme.txt file. The readme.txt offers descriptions of the created templates, similar to those described in the following sections. Application.cfc. This file starts the ColdFusion Application Framework. If the file does not exist, it is created with an OnRequestStart method containing a <cfinclude> tag that specifies the mm_wizard_application_include.cfm, and a simple logout form that displays with every page request for the authenticated user. If the Application.cfc already exists, the wizard creates the OnRequestStart method if one does not exist. If the OnRequestStart already exists, it should simply add the <cfinclude>. mm_wizard_application_include.cfm. The Login Wizard records in this file the authentication parameters entered into the wizard fields. These parameters are passed as arguments to the methods in mm_wizard_authenticate.cfc. mm_wizard_authenticate.cfc. This component contains all the code to perform authentication and authorization, including the <cflogin> container. It contains the following methods: 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. tip Application.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.htm. 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. tip Choosing 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. Table 8.6. <cfntauthenticate> AttributesATTRIBUTE | 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. |
Table 8.7. Fields in the <cfntauthenticate> StructureFIELD | 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. |
tip If you're familiar with performing authentication and authorization in your Application.cfm, move the <cflogin> container into the OnRequestStart method of the Application.cfc. 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 the username 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 username is required"></td> </tr> <tr> <td>password:</td> <td><cfinput type="password" name="j_password" required="yes" message="A password 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 application events. 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 authentication information 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 authentication and login. Assumptions: This template only performs Windows authentication -- all other authentication 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 using either NT authentication."> <cfargument name="args" type="struct" required="true" hint="These are the parameters setup 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 to login."> <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 to clear 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> |