ADOBE
®
COLDFUSION 9 ®
Getting Started
web application construction kit VOLUME 3
Ben Forta and Raymond Camden with Josh Adams, Charlie Arehart, Jeffrey Bouley, Ken Fricklas, Alan Rother, Sarge Sargent, and Matt Tatam
Adobe ColdFusion 9 Web Application Construction Kit, Volume 3: Advanced Application Development Ben Forta and Raymond Camden with Josh Adams, Charlie Arehart, Jeffrey Bouley, Ken Fricklas, Alan Rother, Sarge Sargent, and Matt Tatam This Adobe Press book is published by Peachpit. For information on Adobe Press books, contact: Peachpit 1249 Eighth Street Berkeley, CA 94710 510/524-2178 510/524-2221 (fax) For the latest on Adobe Press books, go to www.adobepress.com To report errors, please send a note to
[email protected] Peachpit is a division of Pearson Education Copyright © 2011 by Ben Forta Series Editors: Rebecca Freed and Karen Reichstein Editor: Judy Ziajka Technical Reviewer: Terry Ryan Production Editor: Tracey Croom Compositor: Maureen Forys, Happenstance Type-O-Rama Proofreader: Liz Welch Indexer: Ron Strauss Cover design: Charlene Charles-Will NOTICE OF RIGHTS
All rights reserved. No part of this book may be reproduced or transmitted in any form by any means, electronic, mechanical, photocopying, recording, or otherwise, without the prior written permission of the publisher. For information on getting permission for reprints and excerpts, contact
[email protected]. NOTICE OF LIABILITY
The information in this book is distributed on an “As Is” basis, without warranty. While every precaution has been taken in the preparation of the book, neither the authors nor Peachpit shall have any liability to any person or entity with respect to any loss or damage caused or alleged to be caused directly or indirectly by the instructions contained in this book or by the computer software and hardware products described in it. TRADEMARKS
Adobe, ColdFusion, ColdFusion Builder, Dreamweaver, Flash, Flash Builder, Flex, and LiveCycle are trademarks or registered trademarks of Adobe Systems, Inc., in the United States and/or other countries. All other trademarks are the property of their respective owners. Many of the designations used by manufacturers and sellers to distinguish their products are claimed as trademarks. Where those designations appear in this book, and Peachpit was aware of a trademark claim, the designations appear as requested by the owner of the trademark. All other product names and services identified throughout this book are used in editorial fashion only and for the benefit of such companies with no intention of infringement of the trademark. No such use, or the use of any trade name, is intended to convey endorsement or other affiliation with this book. ISBN 13: 978-0-321-67920-8 ISBN 10: 0-321-67920-2
9`f^iXg_`\j 9\e =fikX Ben Forta is director of platform evangelism for Adobe Systems Incorporated and has more than two decades of experience in the computer software industry in product development, support, training, and marketing. Ben is the author of the best-selling ColdFusion book of all time, Adobe ColdFusion Web Application Construction Kit, as well as books on SQL, JaveServer Pages, Windows development, Regular Expressions, and more. More than half a million Ben Forta books have been printed in more than a dozen languages worldwide. Ben helped create the official Adobe ColdFusion training material, as well as the certification tests and study guides for those tests. He writes regular columns on ColdFusion and Internet development and spends a considerable amount of time lecturing and speaking on application development worldwide. Ben welcomes your email at WZc5[dgiV#Xdb and invites you to visit his Web site at ]iie/$$[dgiV#Xdb / and his blog at ]iie/$$[dgiV#Xdb$Wad\.
IXp :Xd[\e Raymond Camden is a software consultant focusing on ColdFusion and RIA development. A longtime ColdFusion user, Raymond has worked on numerous ColdFusion books, including Adobe ColdFusion Web Application Construction Kit, and has contributed to the Fusion Authority Quarterly Update and the ColdFusion Developers Journal. He also presents at conferences and contributes to online webzines. He founded many community Web sites, including CFLib.org, ColdFusionPortal.org, and ColdFusionCookbook.org, and is the author of open source applications, including the popular BlogCFC (lll#Wad\X[X#Xdb) blogging application. Raymond is an Adobe Community Professional. He is the happily married proud father of three kids and is somewhat of a Star Wars nut. Raymond can be reached at his blog (lll#XdaY[jh^dc_ZY^#Xdb) or via email at gVn5XVbYZc[Vb^an#Xdb.
:_Xic`\ 8i\_Xik A veteran ColdFusion developer and troubleshooter since 1997 with more than 25 years in IT, Charlie Arehart is a longtime contributor to the ColdFusion community and a recognized Adobe Community Professional. As an independent consultant, he provides short-term troubleshooting and tuning assistance and training and mentoring for organizations of all sizes and ColdFusion experience levels (XVgZ]Vgi#dg\$Xdchjai^c\). Besides running the 2000-member Online ColdFusion Meetup (coldfusionmeetup.com, an online CF user group), he hosts the UGTV repository of recorded presentations from hundreds of speakers (XVgZ]Vgi#dg\$j\ik) and the CF411 site with more than 1000 tools and resources for ColdFusion developers (cf411.com). A certified Advanced ColdFusion Developer and an instructor for each version since ColdFusion 4, Charlie has spoken at each of the major ColdFusion conferences worldwide and is a contributor to all three volumes of Adobe ColdFusion 9 Web Application Construction Kit.
A\]]i\p 9flc\p Jeffrey is director of consulting services at Universal Mind, Inc. He has 16 years of experience in information technology, working on several fronts, from sales to delivery. He has had the opportunity to work with organizations such as NASA, Houghton Mifflin, Accenture, Johnson & Johnson, Bancolombia, Macromedia, Allaire, Quest Technologies Inc., Lockheed Martin, Perot Systems, and AT&T. His technical knowledge covers the back-end databases Oracle 7 through 10 and Microsoft SQL Server 7 through 2005 as well as programming with Flex (ActionScript), ColdFusion, Java, C#, VB.Net, Flash, Active Server pages, Visual Basic (using COM), and ESRI. Jeff enjoys facilitating projects he manages with Agile/SCRUM. Jeffrey earned his master’s degree in management of technology from the University of Miami and holds a bachelor’s degree in information systems from the University of Central Florida.
B\e =i`ZbcXj Ken Fricklas is a long-time ColdFusion author, speaker, and trainer, having used ColdFusion beginning with a slim binder called ColdFusion 1.5. He’s co-founder of several Internet companies, including Mallfinder Network. He lives with his wife and son in Boulder, Colorado, and in his spare time occasionally performs improvisational comedy, listens to and performs music, and enjoys the Colorado mountains on foot and bicycle.
8cXe Ifk_\i Alan Rother currently serves as the director of engineering for Interactive Sites, a leading custom software development firm for the hospitality industry, specializing in content management systems, group business products, and custom systems integration solutions. Alan began working with ColdFusion shortly after graduating from The University of Arizona in late 1999. He is a certified ColdFusion programmer and currently acts as the manager of the Phoenix ColdFusion Users Group in Arizona (lll#VoX[j\#dg\). He can be contacted on his blog (VaVc#gdi]Zg[Vb^an# cZi) or on Twitter (56aVcGdi]Zg).
JXi^\ JXi^\ek Sarge is a former senior product support engineer for ColdFusion and JRun with Adobe’s North American Customer Care organization. During his tenure with Allaire, Macromedia, and now Adobe, he has also supported Breeze/Connect, Contribute Publishing Services, and Flex. He is well-known in the ColdFusion community as an expert in configuration, optimization, scalability, security, and LDAP integration. A Certified ColdFusion Developer and MCSE, he has served as contributor and technical editor or reviewer for several ColdFusion books, written several Developer Connection and Knowledgebase articles for the Adobe Web site, and spoken at several conferences and user groups. Sarge is currently Adobe’s technical account manager for Flash and Flash Media Server. Although his focus is now on serving the Adobe Flash platform community, ColdFusion will forever remain in his blood. Sarge continues to share his onion on his blog at lll#hVg\ZlVn#Xdb.
DXkk KXkXd Matt Tatam has been developing and instructing in ColdFusion for more than 14 years. He has published articles and books on a number of Adobe technologies.
8Zbefnc\[^d\ekj 9\e =fikX Thanks to my co-authors, Ray Camden and Charlie Arehart for their outstanding contributions. Although this book is affectionately known to thousands as “the Ben Forta book,” it is, in truth, as much theirs as it is mine. An extra thank you to Ray Camden for once again bravely accepting the role of lead co-author. Thanks to fellow Adobe Platform Evangelist Terry Ryan for his thorough technical review. Thanks to Nancy Ruenzel and the crew at Peachpit for allowing me the creative freedom to build these books as I see fit. Thanks to Karen Reichstein and Rebecca Freed for bravely stepping in as series editors on this revision, and to Judy Ziajka for so ably shepherding this book through the publication process yet again. Thanks to the thousands of you who write to me with comments, suggestions, and criticism (thankfully not too much of the latter)— I do read each and every message (and even attempt to reply to them all, eventually), and all are appreciated. And last, but by no means least, a loving thank you to my wife Marcy and our children for putting up with (and allowing) my often hectic work schedule. Their love and support make all that I do possible.
IXp :Xd[\e I’d like to thank Ben and Adobe Press for once again asking me to be a part of this incredible series. It is both an honor and a privilege! I’d also like to thank Adobe, specifically Adam Lehman and the engineers. Thanks for having me as part of the ColdFusion 9 beta process and allowing me to help shape the product I love. I promise I’ll ask only half as many annoying questions for ColdFusion 10.
:_Xic`\ 8i\_Xik First, I want to thank Ben for having me as a contributor to this series. With so many excellent authors among the current and past contributors, I really feel privileged. I also want to thank him for all his contributions to the community. Again, as with my fellow authors, I follow in the footsteps of giants. In that regard, I want to acknowledge the awesome ColdFusion community. I’ve so enjoyed being a part of it, as both beneficiary and contributor, since 1997. This book’s for you.
A\]]i\p 9flc\p Many thanks to Ben for including me again in the delivery of a book supporting an incredible product. It never ceases to amaze me how ColdFusion continues to provide companies and the developers who work with it a path to success.
B\e =i`ZbcXj I’d like to thank my wife Carolyn, my son Bryce, and Ben Forta and all the folks at Adobe Press for their patience. I’d also like to thank all my employees and employers over the years for putting up with me.
8cXe Ifk_\i First and foremost I want to thank Ben for giving me the opportunity to contribute to this project, it’s been a really great experience. Sarge, thank you for putting in a good word for me with Ben, and thank you John Bland for encouraging me through the process. Caroline, Blayter, and Nate, thank you for all of your help and support over the years. And to “the boys,” thank you for giving me the time to work on this project and for all of your support for the ColdFusion community.
JXi^\ JXi^\ek Thanks to Ben for having me on the project again. Special thanks to my family for being a rock and a refuge for me. Xtra-special thanks to my wife Nicole for granting me permission to work on this project and for being my “Ambassador of Quon.” Bob!
;\[`ZXk`fej 9\e =fikX Dedicated to the ColdFusion community, a loyal and passionate group that I’ve been proud to call my friends for a decade and a half.
IXp :Xd[\e As always, for my wife. Thank you, Jeanne, for your love and support.
:_Xic`\ 8i\_Xik I’d like to dedicate this book to my wife of 10 years and the love of my life, Kim. I couldn’t do all I do without your patience, support, and encouragement. Thank you, my love. God truly blessed me when He brought you into my life.
A\]]i\p 9flc\p I dedicate this book to my wife Shannon and 2-year-old sons Brennon and Brodie; you supply an incredible richness to my life, a richness that motivates me to be the best I can.
8cXe Ifk_\i This book and everything I do is of course dedicated to my amazing wife Amanda and our wonderful daughter Adisyn; I wouldn’t be anywhere without your love and support.
JXi^\ JXi^\ek As always, I dedicate my work to my fam.
DXkk KXkXd To my family, who remind me daily, what really matters in life.
:FEK<EKJ 8K 8 >C8E:< Introduction G8IK 0
:i\Xk`e^ ?`^_$8mX`cXY`c`kp 8ggc`ZXk`fej
xix (
:?8GK Logging Settings section of the ColdFusion Administrator, you can set a benchmark (in seconds) and display any requests that take longer than the setting. Additionally, you can log all pages that run longer than a given number of seconds to your HZgkZg#ad\. See Figure 47.1 for setting logging of long-running pages. =`^li\ +.%( Log pages that are running too long.
Periodically reviewing all of your logs will create a clear picture of how your ColdFusion applications are functioning and provide information for resolving issues that may arise during the normal course of operation.
AIle D\ki`Zj If you are using the standard version of ColdFusion, or ColdFusion for J2EE deployed on JRun, you can take advantage of yet another set of log files, as well as the enhanced logging capability in JRun. Look in the ColdFusion 9 install directory and go to Qgjci^bZQad\h. You will see the logs listed in Table 47.2. Each of these logs supplies additional information about ColdFusion, although the data is usually not particularly helpful in that much of it is duplicated in the standard ColdFusion logs.
Monitoring Your ColdFusion 9 Server
KXYc\ +.%)
JRun Logs for ColdFusion
LOG FILE NAME
DESCRIPTION
XdaY[jh^dc"Zgg#ad\
Contains ColdFusion stack traces
XdaY[jh^dc"ZkZci#ad\
Contains ColdFusion event log
XdaY[jh^dc"dji#ad\
Logs ColdFusion services events and data from garbage collection
Enhanced ColdFusion logging is another tool that can provide extremely detailed and specific information about a variety of ColdFusion metrics. These metrics are listed in Table 47.3. KXYc\ +.%*
JRun Metrics
METRIC
MEASUREMENT
a^hiZcI]
Threads listening for a new connection
^YaZI]
Threads waiting for a new request
YZaVnI]
Threads waiting to run
WjhnI]
Threads currently running
idiVaI]
Total worker thread count
YZaVnGf
Requests delayed due to high concurrency
YgdeeZYGf
Requests dropped
]VcYaZYGf
Requests handled
]VcYaZYBh
Milliseconds spent servicing requests not including any delay time (YZaVnBh)
YZaVnBh
Milliseconds spent in delay state
WniZh>c
Bytes read from requests
WniZhDji
Bytes written to responses
[gZZBZbdgn
Kilobytes of free memory in the heap
idiVaBZbdgn
Total kilobytes in the heap (in use and free)
hZhh^dch
Current number of active J2EE sessions
hZhh^dch>cBZb
Number of J2EE sessions in memory
As you can see, this is an extensive list of very detailed information! Using JRun metrics, you can see when threads are hanging, when specific requests are not responding, the amount of free memory, and more. The only disadvantage to using JRun metrics is that when they are turned on, they have an impact on system performance. In addition, this feature creates some very large log files, so it’s best to enable it only when you are troubleshooting. To enable JRun metrics, first find your ?Gjc#MBA file, usually found in the ColdFusion root. The path (in Windows) will look something like this: 8/Q8;jh^dcQgjci^bZQhZgkZghQXdaY[jh^dcQH:GK:G">C;Q_gjc#mba
21
22
CHAPTER
47
Monitoring System Performance
After you have found this file you should make a back up since we are going to change this file and if you make any mistakes ColdFusion server may not restart. Usually it is easy enough just make a copy of _gjc#mba and call it _gjcTdg^\^cVa#mba or whatever is easy for you to remember. Now that you have made a backup copy, open _gjc#mba with any text editor. Look for this entry and uncomment it: 1hZgk^XZ XaVhh2ºXdaY[jh^dc#hZgkZg#_gjc)#bZig^Xh#BZig^XhHZgk^XZ6YVeiZgº cVbZ2ºBZig^XhHZgk^XZº3 1Viig^WjiZ cVbZ2ºW^cYId?C9>º3igjZ1$Viig^WjiZ3 1$hZgk^XZ3
Then find this entry: 1hZgk^XZ XaVhh2º_gjcm#ad\\Zg#Ad\\ZgHZgk^XZº cVbZ2ºAd\\ZgHZgk^XZº3
and edit its attributes. You want to change bZig^Xh:cVWaZY to True, and bZig^XhAd\;gZfjZcXn (the interval, in seconds, to log metrics) to somewhere between 5 and 10 seconds. So you should have something that looks like this: 1Viig^WjiZ cVbZ2ºbZig^Xh:cVWaZYº3igjZ1$Viig^WjiZ3 1Viig^WjiZ cVbZ2ºbZig^XhAd\;gZfjZcXnº3*1$Viig^WjiZ3
The information that will be recorded to the logs will look something like this: &%$&) &'/&&/'( bZig^Xh LZW i]gZVYh Wjhn$idiVa/ %$' HZhh^dch/ ' IdiVa BZbdgn2,%*' ;gZZ2((%(
Next, split the logged information into its own log file. Do this by editing the line 1Viig^WjiZ cVbZ2ºÄaZcVbZº3p_gjc#gddiY^gr$ad\h$p_gjc#hZgkZg#cVbZr"ZkZci#ad\1$Viig^WjiZ3
so that it reads like this: 1Viig^WjiZ cVbZ2ºÄaZcVbZº3p_gjc#gddiY^gr$ad\h$p_gjc#hZgkZg#cVbZr" pad\#aZkZar# ad\1$ Viig^WjiZ3
Once you have changed the _gjc#mba file, you will need to save the file and restart ColdFusion for these settings to take effect. Once you restart ColdFusion you will see that all the metrics data you record while troubleshooting will go to a separate log, XdaY[jh^dc"bZig^Xh#ad\. EFK
9% @] pfl Ôe[ k_Xk pfl e\\[ \m\e dfi\ d\dfip# jn`kZ_`e^ kf -+$Y`k _Xi[nXi\# X -+$Y`k A):#[jaacVbZ1$X[djieji31$W31Wg3 Ndjg hZXjg^in aZkZa ^h " 1X[djieji38DD@>:#jhZgHZXjg^in1$X[djieji3 1X[ZahZ3 1X[eVgVb C6B:2ºdg^\^cJGAº 9:;6JAI2º8#hXg^eiTcVbZ48#fjZgnThig^c\º3 1XÅdXVi^dc JGA2º$ad\^c#X[b4dg^\^cJGA2jga:cXdYZY;dgbVidg^\^cJGAº3 1X[VWdgi3 1$XÄ[3
Consider the following issues with using cookies to store session state: N
Clients may turn off or filter cookies using cookie-blocking software.
N
Clients may be behind a firewall or proxy server that prevents cookie transmission.
N
Cookies have a size limit, and most browsers limit the total number of stored cookies to 300 and allow only 20 per domain.
N
Cookies may be stored in plain text, revealing private information about the user.
Because a user might access your site from more than one machine or browser (or might experience a system crash that wipes out cookies), it’s usually best to store a minimal user identifier in a cookie and keep critical data on the server side. It is possible to track a user’s state through an application by carrying the variables along on the client side, either in name-value pairs in the URL or in a client-side cookie. Information stored in cookies can be either name-value pairs or complex WDDX packets, storing a structure of information about the user. Carrying this data around in the URL is a painstaking, difficult-tomaintain practice, and even the most intrepid Web developer should think twice before going down this road. The upside of this strategy is that it does not matter to the system whether a user is redirected to another machine. All the information the script needs is contained in the URL referencing it.
Options for Managing Session State
Storing this information in cookies is easier to implement and allows storage of complex data structures in the form of WDDX packets. You can further simplify this scheme by specifying cookies as the default repository for client variable storage in ColdFusion Administrator. The downside of using cookies is that because they are maintained solely on the client side, an enterprising user can hack the application by modifying the cookies. The following sections examine ColdFusion-specific solutions for implementing session-state management.
Lj`e^ J\jj`fe MXi`XYc\j m\ijlj :c`\ek MXi`XYc\j ColdFusion offers two methods for developers to maintain session state when running on the traditional ColdFusion application server platform: client variables and session variables. This section discusses the benefits and risks of using these two variables for implementing session state in a clustered environment. To use client or session variables, ColdFusion sets two values for each user: 8;>9, a sequential client identifier, and 8;ID@:C, a random-number client-security token. These two variables will uniquely identify a user to ColdFusion and help maintain state. Session variables exist in memory on the server that initiated the session with the user. This is an issue in a clustered Web site. The user’s session will be lost upon transfer to another server in the cluster. The new server will not know about the prior session and will start a new session with the user. Session-aware load balancing can resolve this problem by keeping a user on the same server throughout the session (see the discussion of this topic in “Keeping the User on the Same Machine” later in this chapter). This server becomes a single point of failure, and you risk the server’s crashing and losing the user session. Client variables can exist in three ways: in the server’s Registry, in a database, or in cookies. To use client variables in a clustered environment, you should store them either in a centrally located database or as cookies to share among all servers in the cluster. Keep in mind that there are serious problems with storing client variables in the Registry. On high-volume sites, storing too many persistent variables in the Registry will eventually overflow the Registry, causing instability and server crashes. If you must store client variables in the Registry, set the purge setting in ColdFusion Administrator to a low value to reduce the possibility of filling up your Registry. EFK
C;$X[jh^dc$eVX`V\Zh$pVgX]^kZTcVbZr ]fi :fc[=lj`fe A)C;$X[jh^dc$W^c (J2EE configurations) directory. You can use this utility for N
Converting ColdFusion source code into Java bytecode for sourceless deployment of ColdFusion templates
N
Precompiling ColdFusion templates into Java class files
The basic syntax for calling the X[Xdbe^aZ script is as follows: X[Xdbe^aZ P"YZeadnR lZWgddi PY^gZXidgn"id"Xdbe^aZR Pdjieji"Y^gZXidgnR
It is preconfigured with the options necessary to compile source code into Java bytecode for sourceless deployment, and for compiling ColdFusion templates into Java class files.
:fdg`c`e^ JfliZ\c\jj K\dgcXk\j The capability to deploy sourceless ColdFusion templates is one of the most anticipated ColdFusion 9 features. Sourceless means you can deploy your ColdFusion templates (CFM, CFC, and CFR files) as Java bytecode and distribute them without changing the template names or paths. The templates will contain unreadable Java bytecode but will run as if they contained CFML. This makes source code distribution more secure and protects the intellectual property contained in the files. For more information on the security of sourceless deployment, see the “Encrypting ColdFusion Templates” section of Chapter 56, “Security in Shared and Hosted Environments.” Use the X[Xdbe^aZ utility with the ·YZeadn option to convert the source code of your ColdFusion templates to Java bytecode. The utility will make a copy of your original template and compile the CFML to Java bytecode. The template containing the Java bytecode will be written to the specified destination directory, leaving unchanged your original CFML templates. The X[Xdbe^aZ executable is located in the X[Tgddi$W^c (server configuration) or X[TlZWVeeTgddi$L:7">C;$X[j" h^dc$W^c ( J2EE configurations) directory. Use the following command to compile your templates to Java bytecode: X[Xdbe^aZ "YZeadn lZWgddi Y^gZXidgn"id"Xdbe^aZ djieji"Y^gZXidgn
Table 51.3 describes the X[Xdbe^aZ parameters for creating sourceless templates.
121
122
CHAPTER
51
Deploying Applications
KXYc\ ,(%* X[Xdbe^aZ Script Options for Sourceless Deployment OPTION
DESCRIPTION
REQUIRED?
lZWgddi
Specify the fully qualified path to the Web server root directory (for instance, 8/Q 8daY;jh^dc.Qlllgddi or 8/Q>cZiejWQ lllgddi).
Yes
Y^gZXidgn"id"Xdbe^aZ
Specify the fully qualified path to the Yes directory containing the templates to be compiled. This directory must be under the specified lZWgddi directory. If omitted, ColdFusion will compile all ColdFusion templates in the specified lZWgddi directory.
djieji"Y^gZXidgn
Yes Specify the fully qualified path to the destination directory that will contain the compiled deployable files. This cannot be the same directory as the source directory.
Gi\Zfdg`c`e^ :fc[=lj`fe K\dgcXk\j As you may know, the ColdFusion server compiles each ColdFusion template into Java bytecode when the template is initially requested—that is, the first time after a server restart. When the “Save class files” option in ColdFusion Administrator is enabled, the compiler writes the bytecode into Java #XaVhh files on the disk and then copies the bytecode into memory (the Template Cache); otherwise, the bytecode is written directly to the Template Cache. This compilation process increases the initial page request. ColdFusion will continue serving the template from the Template Cache, so that only the initial request takes the compilation hit. Combining this technique with the Trusted Cache option can dramatically improve site performance. Adobe recommends saving the class files only for production servers. Use the following command to compile ColdFusion templates (CFM, CFC, and CFR files) into Java class files: X[Xdbe^aZ lZWgddi Y^gZXidgn"id"Xdbe^aZ
Table 51.4 summarizes the script options. KXYc\ ,(%+ X[Xdbe^aZ Script Options for Precompiling #XaVhh Files OPTION
DESCRIPTION
REQUIRED?
lZWgddi
Specify the fully qualified path to the Web server root directory (for instance, 8/Q8daY;jh^dc.Q lllgddi or 8/Q>cZiejWQlllgddi).
Yes
Y^gZXidgn"id"Xdbe^aZ
Specify the fully qualified path to the directory containing the templates to be compiled. This directory must be under the specified lZWgddi directory. If omitted, ColdFusion will compile all ColdFusion templates in the specified lZWgddi directory.
Yes
ColdFusion Compiler
K@G
Efk`Z\ k_Xk k_\ Y^gZXidgn"id"Xdbe^aZ dljk Y\ n`k_`e k_\ jg\Z`Ô\[ lZWgddi% @] pfl nXek kf Zfdg`c\ k\dgcXk\j flkj`[\ f] k_\ XZklXc lZWgddi kf ZcXjj Ôc\jÇjlZ_ Xj k\dgcXk\j `e X N\Y j\im\i m`iklXc [`i\Zkfip ZXcc\[ IZhi^c\Çk_\e jg\Z`]p k_Xk [`i\Zkfip Xj k_\ lZWgddi Xe[ fd`k k_\ Y^gZXidgn"id"Xdbe^aZ gXiXd\k\i1 X[Xdbe^aZ 8/QIZhi^c\%
The compiled class files are stored in the X[Tgddi$llgddi$L:7">C;$X[XaVhhZh (server configuration) or X[TlZWVeeTgddi$L:7">C;$X[XaVhhZh (J2EE configurations) directory. The files are renamed using a unique syntax: X[
ÄaZcVbZ
]Vh] XdYZ
#XaVhh
ColdFusion uses the following to derive this file name: N
The ÄaZcVbZ is extracted from a Java File object created from the canonical file name (for example, 8/QIZhi^c\Q]Vh]Zg#X[b) with the following substitutions: Included slashes ($) in the file name are replaced with a double underscore ( T T ). Any characters that are illegal in a Java identifier are replaced with their equivalent twodigit hexadecimal number; for example, a period (#) becomes 'Z.
N
The ]Vh] XdYZ represents the hash code value created by the Java File object (_VkV# ^d#;^aZ). The hash code is generated by calling the ]Vh]8dYZ method; refer to the Java documentation at ]iie/$$_VkV#hjc#Xdb$_VkVhZ$+$YdXh$Ve^$_VkV$^d$;^aZ#]iba]Vh]8dYZ. If the value returned by ]Vh]8dYZ is negative, it is exclusive-or’d with 0xFFFFFFFF to get the value ColdFusion uses.
K@G
Pfl n`cc Xcjf j\\ #XaVhh Ôc\j n`k_ X [fccXi j`^e `e k_\ eXd\ ]fccfn\[ Yp X ]leZk`fe eXd\# Xj `e X[6eea^XVi^dc'ZX[X +(.(&%-.'[jcXDCG:FJ:HIHI6GI#XaVhh% K_\ i\gi\j\ekj k_\ Zfdg`c\[ :fc[=lj`fe lj\i$[\Ôe\[ ]leZk`fe L;=
ZXccj n`k_`e k_\ Ôc\% K_`j `j dfi\ Zfddfe ]fi :fc[=lj`fe :fdgfe\ekj :=: Ôc\j# Ylk k_\p n`cc fZZli ]fi Xep :fc[=lj`fe k\dgcXk\ ZfekX`e`e^ L;= ZXccj%
:fc[=lj`fe K\dgcXk\ ;\gcfpd\ek :fej`[\iXk`fej At first glance, the difference in the command syntax for compiling your ColdFusion templates to #XaVhh files as compared with compiling to sourceless code is the ·YZeadn option. However, the real difference is the process by which the code is compiled. When precompiling (or not using the ·YZeadn option), the compiler translates the CFML into Java bytecode and writes the bytecode to a #XaVhh file. When creating sourceless templates, the compiler implements the ColdFusion runtime service, translates the CFML into Java bytecode, and then creates a new template (with the same name as the original) and writes the bytecode into that template. Implementing the run-time service allows the compiler to check the code for syntax errors—as if the code were called from the browser. The compiler will fail and return if there are any errors in your code. The error and stack trace are recorded to the ColdFusion exception log (X[gddiQad\hQZmXZei^dc#ad\). K@G
K_\ ·YZeadn fgk`fe n`cc ZXkZ_ Zfdg`cXk`fe \iifij# Ylk jfd\ ile$k`d\ \iifij n`cc efk fZZli lek`c X]k\i [\gcfpd\ek% =fi \oXdgc\# ÈK\dgcXk\ efk ]fle[É \iifij ]fi XÄcXajYZ n`cc efk fZZli lek`c k_\ [\gcfp\[ Ôc\ `j ile fe k_\ [\gcfp\[ jpjk\d%
123
124
CHAPTER
51
Deploying Applications
Adobe provided the X[Xdbe^aZ script with ColdFusion for precompiling #XaVhh files. Some developers have tried deploying these files on other systems. Adobe does not recommend deploying compiled #XaVhh files, however, because they are largely dependent on the underlying directory structure of the source server. Some of the class files might actually work on the deployment server. Adobe created the ·YZeadn option to enable the secure deployment of ColdFusion templates.
:ljkfd`q`e^ k_\ X[Xdbe^aZ JZi`gk You can customize the X[Xdbe^aZ script file that ships with ColdFusion 9, or build your own. Table 51.5 provides a complete list of ColdFusion Compiler options. The X[Xdbe^aZ script preconfigures some of these options for you. Examine the preconfigured values to ensure that the script will run on your system. K@G
Pfl ZXe Zfdg`c\ `e[`m`[lXc Ôc\j Yp jg\Z`]p`e^ k_\ ]lccp hlXc`Ô\[ gXk_ kf k_\ Ôc\ `ejk\X[ f] aljk k_\ [`i\Zkfip gXk_% =fi \oXdgc\1 X[Xdbe^aZ 8/Q>cZiEjWQlllgddi 8/Q>cZiEjWQlllgddiQ^cYZm#X[b%
KXYc\ ,(%,
ColdFusion Compiler Command Options
OPTION
DESCRIPTION
REQUIRED
X[gddi
The fully qualified path to the ColdFusion root directory (such as 8/Q8daY;jh^dc. or $dei$ XdaY[jh^dc.).
Yes
Y or YZeadn
Compile templates for sourceless deployment.
Yes for Sourceless Deployment
YZeadnY^g
The fully qualified path to the directory that will contain the compiled deployable files. This cannot be the same directory as the source directory.
Yes for Sourceless Deployment
[ or [dgXZ
Force compilation.
No
\ or YZWj\
Enable debug symbols.
No
]Zae
Displays usage information and available options.
No
hgXY^g
The fully qualified path to the directory containing the Yes templates to be compiled. This directory must be under the specified lZWgddi directory. If omitted, ColdFusion will compile all ColdFusion templates in the specified lZWgddi directory.
lZW^c[
The fully qualified path to the ColdFusion L:7">C; directory.
Yes
lZWgddi
The fully qualified path to the Web server root directory (such as 8/Q8daY;jh^dc.Qlllgddi or 8//Q>cZiejWQlllgddi.
Yes
k or kZgWdhZ
Display compiler performance statistics.
No
Choosing the Right Deployment Option
With the options in Table 51.5, you can create your own compiler script using syntax similar to the following: _VkV "Xe ¹X/Q8daY;jh^dc.Qgjci^bZQa^WQ_gjc#_Vg08/Q8daY;jh^dc.QlllgddiQL:7">C;Qa^WQX[bmT WddihigVe#_Vg08/Q8daY;jh^dc.QlllgddiQL:7">C;Qa^WQX[m#_Vgº "9XdaY[jh^dc#XaVhhEVi]28/$ 8daY;jh^dc.$a^W$jeYViZh!8/$8daY;jh^dc.$a^W "9XdaY[jh^dc#a^WEVi]28/$8daY;jh^dc.$a^W XdaY[jh^dc#iddah#8dbbVcYA^cZ>ckd`Zg 8dbe^aZg "X[gddi 8/Q8daY;jh^dc. "lZW^c[ 8/Q 8daY;jh^dc.QlllgddiQL:7">C; "lZWgddi 8/Q8daY;jh^dc.Qlllgddi "YZeadn "hgXY^g 8/Q IZhi^c\QYZeadn "YZeadnY^g 8/QIZhi^c\QhdjgXZ ·k
This command will compile all the ColdFusion templates (CFM, CFC, and CFR files) in the 8/Q directory and save the Java bytecode versions in the 8/QIZhi^c\QhdjgXZ directory. The original files in 8/QIZhi^c\QYZeadn will retain the original CFML in a human-readable format.
IZhi^c\QYZeadn
EFK
cZiEjWQlllgddi 8/Q>cZiEjWQlllgddiQ^cYZm#X[m 8/QIZhi^c\QhdjgXZ% @] pfl kip lj`e^ X n`c[ZXi[ Xj `e 8/Q>cZiEjWQlllgddiQ#X[m # fecp k_\ Ôijk Ôc\ `j Zfdg`c\[% J\\ k_\ ÈJ\kk`e^ k_\ =`c\ EXd\ KdgHVai parameter. Specify your own count to the ^iZgVi^dch parameter. Use the ColdFusion 9ZXgnei function to decipher a string that has been encrypted with the :cXgnei function. 9ZXgnei and :cXgnei are mirror functions in that they require the same argu-
ments (see the section “:cXgnei and 9ZXgnei Parameters” later in this chapter). Remember that ColdFusion’s encryption is symmetric—you must use the same key to encrypt and decrypt the string. If you use strong encryption (a Block or PBE algorithm) to encrypt the string, then you need to use the same key (seed) or password (salt), algorithm, and >KdgHVai and ^iZgVi^dch values to decrypt it. Listing 52.1 shows an example of the use of strong encryption with :cXgnei and 9ZXgnei. C`jk`e^ ,)%( ZcXgneiZg#X[b —The :cXgnei and 9ZXgnei Functions at Work 1X[hZii^c\ ZcVWaZX[djiejidcan2ºnZhº3 1""" CVbZ d[ ÄaZ/ ZcXneiZg#X[b 9ZhXg^ei^dc/ 9ZbdchigViZh higdc\ Va\dg^i]bh jhZY ^c :cXgnei VcY 9ZXgnei [jcXi^dch# HVg\Z hVg\Z5VYdWZ#Xdb lll#VYdWZ#Xdb$\d$hVg\ZTWad\ 9ViZ XgZViZY/ ;ZWgjVgn .! '%%* 9ViZ bdY^ÄZY/ BVgX] &.! '%&% """3 1X[hZii^c\ ZcVWaZX[djiejidcan2ºcdº3 19D8INE: =IBA EJ7A>8 "$$L(8$$9I9 =IBA )#% IgVch^i^dcVa$$:C3 1]iba3 1]ZVY3 1i^iaZ38daY;jh^dc . :cXgnei^dc IZhi1$i^iaZ3 1$]ZVY3 1WdYn3 1]'38daY;jh^dc . :cXgneiZg1$]'3 1X[[dgb ^Y2ºZcXgneiZgº cVbZ2ºZcXgneiZgº3
133
134
CHAPTER
C`jk`e^ ,)%(
52
Understanding Security
(continued)
1iVWaZ WdgYZg2º%º3 1ig31iY3Hig^c\/ 1$iY31iY31XÄceji ineZ2ºiZmiº ^Y2ºeaV^cIZmiº cVbZ2ºeaV^cIZmiº h^oZ2º'*º gZfj^gZY2ºnZhº bZhhV\Z2ºNdj bjhi egdk^YZ V hig^c\ id ZcXgnei#º31$iY31$ig3 1ig31iY3@Zn/1$iY31iY31^ceji ineZ2ºiZmiº ^Y2º`Znº cVbZ2º`Znº h^oZ2º'*º Y^hVWaZY31$ iY31$ig3 1ig31iY36a\dg^i]b/1$iY3 1iY31X[hZaZXi ^Y2ºVa\dº cVbZ2ºVa\dº dc8]Vc\Z2º^[Va\d#kVajZ#^cYZmD[»E7:¼p`Zn# Y^hVWaZY2igjZr ZahZ p`Zn#Y^hVWaZY2[VahZrº3 1dei^dc kVajZ2º6:Hº36:H1$dei^dc3 1dei^dc kVajZ2º7adlÄh]º37adlÄh]1$dei^dc3 1dei^dc kVajZ2º9:Hº39:H1$dei^dc3 1dei^dc kVajZ2º9:H:9:º3Ig^eaZ 9:H1$dei^dc3 1dei^dc kVajZ2ºE7:L^i]B9*6cY9:Hº3EVhhldgY L^i] 9:H1$dei^dc3 1dei^dc kVajZ2ºE7:L^i]B9*6cYIg^eaZ9:Hº3EVhhldgY L^i] Ig^eaZ9:H1$dei^dc3 1dei^dc kVajZ2ºE7:L^i]H=6&6cY9:HZYZº3E7:L^i]H=6&6cY9:HZYZ1$dei^dc3 1dei^dc kVajZ2ºE7:L^i]H=6&6cYG8'T)%º3E7:L^i]H=6&6cYG8'T)%1$dei^dc3 1$X[hZaZXi31$iY31$ig3 1ig31iY3:cXdY^c\/1$iY3 1iY31X[hZaZXi ^Y2ºZcXdYZº cVbZ2ºZcXdYZº3 1dei^dc kVajZ2ºJJº3JJZcXdYZ1$dei^dc3 1dei^dc kVajZ2º7VhZ+)º37VhZ+)1$dei^dc3 1dei^dc kVajZ2º=Zmº3=:M1$dei^dc3 1$X[hZaZXi31$iY31$ig3 1ig31iY3cWhe01$iY31iY31^ceji ineZ2ºhjWb^iº cVbZ2ºHjWb^iº kVajZ2ºHjWb^iº3cWhe0cWhe0 1^ceji cVbZ2ºGZhZiº ineZ2ºGZhZiº31$iY31$ig3 1$iVWaZ3 1$X[[dgb3 1Wg $3 1V ]gZ[2º^cYZm#X[bº37VX` id ^cYZm1$V3 1X[hZii^c\ ZcVWaZX[djiejidcan2ºnZhº3 1XÄ[ ^h9ZÄcZY»;DGB#Va\d¼3 1""" HZi V YZ[Vjai `Zn kVajZ ^c XVhZ jhZg YdZh cdi hjWb^i dcZ dg 7adX` :cXgnei^dc ^h jhZY# """3 1""" 9ZiZXi EVhhldgY 7VhZY :cXgnei^dc Va\dg^i]bh# """3 1XÄ[ J8VhZAZ[i;DGB#Va\d!( :F ¹E7:º3 1""" 8gZViZ V YZ[Vjai `Zn [dg EVhhldgY 7VhZY :cXgnei^dc Va\dg^i]b# """3 1XÄ[ CDI aZcig^b;DGB#`Zn3 1X[hZi kVg^VWaZh#`Zn 2 ¹Bn hZXgZi eVhhldgY hig^c\º $3 1X[hZi kVg^VWaZh#Vjid@Zn 2 igjZ $3 1X[ZahZ3 1X[hZi kVg^VWaZh#`Zn 2 ig^b;DGB#`Zn $3 1X[hZi kVg^VWaZh#Vjid@Zn 2 [VahZ $3 1$XÄ[3 1X[ZahZ3 1""" JhZ \ZcZgViZHZXgZi@Zn id XgZViZ V hZXjgZ! gVcYdb `Zn [dg i]Z X]dhZc 7adX` :cXgnei^dc Va\dg^i]b# """3 1X[hZi kVg^VWaZh#`Zn 2 \ZcZgViZHZXgZi@Zn;DGB#Va\d $3 1X[hZi kVg^VWaZh#Vjid@Zn 2 igjZ $3 1$XÄ[3 1""" EZg[dgb ZcXgnei^dc l^i] YZ[Vjai 8daY;jh^dc 8dbeVi^WaZ Va\dg^i]b 8;BMT 8dbeVi# """3 1X[hZi kVg^VWaZh#XdbeViIZmi 2 ZcXgnei;DGB#eaV^cIZmi! kVg^VWaZh#`Zn $3 1""" EZg[dgb ZcXgnei^dc$YZXgnei^dc l^i] higdc\ Va\dg^i]bh# """3
Encryption
C`jk`e^ ,)%(
(continued)
1X[hZi kVg^VWaZh#X^e]ZgIZmi 2 ZcXgnei;DGB#eaV^cIZmi! kVg^VWaZh#`Zn! ;DGB#Va\d! ;DGB#ZcXdYZ $3 1X[hZi kVg^VWaZh#dg^\IZmi 2 YZXgneikVg^VWaZh#X^e]ZgIZmi! kVg^VWaZh#`Zn! ;DGB# Va\d! ;DGB#ZcXdYZ $3 1X[djieji3 1]g3 1iVWaZ WdgYZg2º%º3 1ig31i] Va^\c2ºaZ[iº3Dg^\^cVa Hig^c\/1$i]31iY3;DGB#eaV^cIZmi1Wg31$iY31$ig3 1ig31i] Va^\c2ºaZ[iº3@Zn 6jid 8 "$$L(8$$9I9 =IBA )#% IgVch^i^dcVa$$:C3 1]iba3 1]ZVY3 1i^iaZ38daY;jh^dc . =Vh] IZhi1$i^iaZ3 1$]ZVY3 1WdYn3 1]'38daY;jh^dc . =Vh]Zg1$]'3 1X[[dgb cVbZ2º]Vh]Zgº3 1iVWaZ WdgYZg2º%º3 1ig31iY3Hig^c\/ 1$iY31iY31XÄceji ineZ2ºiZmiº cVbZ2ºeaV^cIZmiº h^oZ2º'*º gZfj^gZY2ºnZhº bZhhV\Z2ºNdj bjhi egdk^YZ V hig^c\ id ]Vh]#º31$iY31$ig3 1ig31iY36a\dg^i]b/1$iY31iY31X[hZaZXi cVbZ2ºVa\dº3
Encryption
C`jk`e^ ,)%)
(continued)
1dei^dc kVajZ2ºB9'º3B9'1$dei^dc3 1dei^dc kVajZ2ºB9*º3B9*1$dei^dc3 1dei^dc kVajZ2ºH=6º3H=6"&1$dei^dc3 1dei^dc kVajZ2ºH=6"'*+º3H=6"'*+1$dei^dc3 1dei^dc kVajZ2ºH=6"(-)º3H=6"(-)1$dei^dc3 1dei^dc kVajZ2ºH=6"*&'º3H=6"*&'1$dei^dc3 1$X[hZaZXi31$iY31$ig3 1ig31iY3:cXdY^c\/1$iY3 1iY31X[hZaZXi cVbZ2ºZcXdYZº3 1X[djieji3 1XÅdde XdaaZXi^dc2ºX]VgHZihº ^iZb2ºhZiº3 1dei^dc kVajZ2ºX]VgHZihPhZiRº 1XÄ[ ÄcYCd8VhZ;DGB#ZcXdYZ! hZi3hZaZXiZY1$ XÄ[33X]VgHZihPhZiR1$dei^dc3 1$XÅdde31$X[djieji3 1$X[hZaZXi31$iY31$ig3 1ig31iY3cWhe01$iY31iY31^ceji ineZ2ºhjWb^iº cVbZ2ºHjWb^iº kVajZ2ºHjWb^iº3cWhe0cWhe0 1^ceji cVbZ2ºGZhZiº ineZ2ºGZhZiº31$iY31$ig3 1$iVWaZ31Wg $3 1$X[[dgb3 1V ]gZ[2º^cYZm#X[bº37VX` id ^cYZm1$V3 1X[hZii^c\ ZcVWaZX[djiejidcan2ºnZhº3 1XÄ[ ^h9ZÄcZY»;DGB#Va\d¼3 1""" EZg[dgb i]Z ]Vh] jh^c\ hjWb^iiZY Va\dg^i]b VcY ZcXdY^c\# """3 1X[hZi kVg^VWaZh#i]Z=Vh] 2 ]Vh];DGB#eaV^cIZmi! ;DGB#Va\d! ;DGB#ZcXdYZ3 1X[djieji3 1]g3 1iVWaZ WdgYZg2º%º3 1ig31i] Va^\c2ºaZ[iº3Dg^\^cVa Hig^c\/1$i]31iY3;DGB#eaV^cIZmi1Wg31$iY31$ig3 1ig31i] Va^\c2ºaZ[iº38; =Vh]/1$i]31iY hinaZ2ºXdadg/;;%%%%º3]Vh];DGB# eaV^cIZmi1$iY31$ig3 1ig31i] Va^\c2ºaZ[iº3;DGB#Va\d =Vh]/1$i]31iY hinaZ2ºXdadg/%%..%%º3kVg^VWaZh# i]Z=Vh]1Wg31$iY31$ig3 1ig31i] Va^\c2ºaZ[iº3=Vh] AZc\i]/1$i]31iY hinaZ2ºXdadg/%%..88º3aZcIg^bkVg^VW aZh#i]Z=Vh] X]VgVXiZgh1$iY31$ig3 1ig31i] Va^\c2ºaZ[iº3:cXdY^c\/1$i]31iY hinaZ2ºXdadg/%%..%%º3;DGB#ZcXdYZ1$ iY31$ig3 1$iVWaZ3 1$X[djieji3 1$XÄ[3 1X[hZii^c\ ZcVWaZX[djiejidcan2ºcdº3 1$WdYn3 1$]iba3
Listing 52.2 shows how to hash a string with strong algorithms (Figure 52.2). Because it provides one-way encryption, =Vh] creates a fingerprint of the original string. This fingerprint is useful for storing sensitive data in a database so that it remains saved if the database security is compromised. You can then compare a hash of a user-submitted string to the fingerprint in the database. This process is very useful for passwords, for example: 1X[fjZgn cVbZ2ºX]ZX`jhZgº YViVhdjgXZ2ºYhcº3 H:A:8I jhZg>9 ;GDB jhZg L=:G: jhZgcVbZ 2¼;DGB#jhZgcVbZ¼ VcY eVhhldgY 2¼=Vh];DGB#eVhhldgY! ;DGB#Va\dg^i]b¼ 1$X[fjZgn3
141
142
CHAPTER
52
Understanding Security
=`^li\ ,)%) The original ColdFusioncompatible, and strong-algorithmhashed string output from Listing 52.2. Encoding display will vary depending on system-supported character sets.
K@G
8j n`k_ k_\ :cXgnei Xe[ 9ZXgnei ]leZk`fej# pfl dljk lj\ k_\ jXd\ Xc^fi`k_d n_\e ZfdgXi`e^ _Xj_\[ jki`e^j%
Of course, neither =Vh] nor :cXgnei will protect data being sent from the client’s browser to the server. For this, you’ll need to use SSL. SSL is a commonly used protocol for securing Internet transmissions. It operates between the application (HTTP) and transport (TCP) layers of the OSI open systems interconnectivity (OSI) model. SSL clients are included as part of most major browsers, and the SSL protocol is built into most modern Web servers. SSL uses the public-and-private key encryption system from RSA (]iie/$$lll#ghVhZXjg^in#Xdb), including digital certificates. Thus, the responsibility for securing data as it travels across the Internet is not ColdFusion’s.
=fiZ`e^ X GX^\ I\hl\jk kf Lj\ JJC Although ColdFusion has no part in the SSL handshake (it is strictly a function between the browser and Web server), under certain situations developers can ensure that secure ColdFusion templates are only accessed via SSL: 1XÄ[ ÄcYCd8VhZ¹d[[º! 8#=IIEH dg CDI 8#H:GK:GTEDGITH:8JG:3 1XÅdXVi^dc jga2º]iieh/$$X\^#hZgkZgTcVbZX\^#hXg^eiTcVbZ4X\^#fjZgnThig^c\º hiVijh8dYZ2¹(%&º VYYId`Zc2¹[VahZº3 1X[VWdgi3 1$XÄ[3
This code begins by checking the CGI =IIEH variable, which is set to dc when a connection is SSL. It also checks the CGI H:GK:GTEDGITH:8JG: variable, which has a value of & when the Web server port is secured via SSL. If 8#=IIEH is set to d[[ or 8#H:GK:GTEDGITH:8JG: is set to % (false), the 18;AD86I>DC3 tag redirects the user to the same page using the HTTPS protocol with a HTTP 301 status code.
Browser Validation
EFK
@ mXi`XYc\j% Jfd\ N\Y j\im\i ZfeÔ^liXk`fe dXp Y\ i\hl`i\[ kf gifg\icp gfglcXk\ k_\j\ mXi`XYc\j%
JJC C`XY`c`k`\j Although SSL is great for encrypting communications between the client and Web server, handling the encrypting and decrypting puts an enormous burden on the Web server, impeding performance. For this reason, it’s important only to use SSL when sensitive data is being passed. SSL accelerators, hardware-based solution that offloads the SSL processing from the Web server, can vastly improve performance. Unfortunately, these accelerators can be quite expensive and are often too costly for use in many applications.
J\Zli`e^ :fc[=lj`fe `e ;`jki`Ylk\[ Df[\ If you are concerned about snooping on your wire, consider encrypting the connections between the major parts of your application: the Web server, ColdFusion server, and database server. Typically, ColdFusion and the Web server reside on the same machine, so you only need to worry about the network connection to the database. However, ColdFusion is capable of running in Distributed mode, where the Web server is on a completely separate machine. In this configuration, you may also want to encrypt the connections between all machines: ColdFusion to Web server, ColdFusion to database server, and Web server to database server (if necessary). You can do this with SSL, with hardware, or with a virtual private network (VPN). As mentioned in the section “SSL Liabilities,” SSL communications tend to be slow, and hardware accelerators are expensive. VPNs are widely used in server farms, where each machine has at least two NICs— one with a publicly accessible IP Address, the other with a private address. All internal inter-server communication happens on the VPN private address. =fi dfi\ `e]fidXk`fe fe ZfeÔ^li`e^ :fc[=lj`fe `e ;`jki`Ylk\[ df[\ m\ij`fej -%oÆ. # j\\ k_\ ÈIlee`e^ DXZifd\[`X :fc[=l$ j`fe `e ;`jki`Ylk\[ Df[\É Xik`Zc\ `e DXZifd\[`X :fc[=lj`fe ;\m\cfg\i :\ek\i# Xk ]iie/$$lll#VYdWZ#Xdb$hjeedgi$ XdaY[jh^dc$VYb^c^higVi^dc$X[bmT^cTY^hig^WjiZYTbdYZ$% J\\ Xcjf K\Z_Efk\ 8ik`Zc\ ()(X'Y)0# ÈDXel$ Xccp :feÔ^li`e^ k_\ N\Y J\im\i :fee\Zkfi ]fi ;`jki`Ylk\[ :fc[=lj`fe DO JkXe[Xcfe\#É Xk ]iie/$$\d#VYdWZ#Xdb$`W$ ihT&'&V%W'.TZc"jh%
9ifnj\i MXc`[Xk`fe The Web server is responsible for securing data from prying eyes as it traverses the Internet to the browser. However, the Web server cannot guarantee the integrity of the data exchanged between
143
144
CHAPTER
52
Understanding Security
the client and the back-end system. Hackers can still compromise sites running SSL. Because it is the doorway to the back-end systems, protecting the site from these attacks is ColdFusion’s job. Cross-site scripting, tampered form and URL values, and contaminated file uploads are methods used by hackers and script bunnies to attack your site. Validating all browser input is the most effective panacea for these attacks. ColdFusion provides several function and tag countermeasures that should be fundamental parts of every methodology for securing ColdFusion applications.
:ifjj$J`k\ JZi`gk`e^ OJJ In February 2000, CERT (]iie/$$lll#XZgi#dg\), DoD-CERT (]iie/$$lll#XZgi#b^a), and others, created the term cross-site scripting (XSS) to describe the injection of code by one source into the Web pages of another source. This attack involves using cookies, form and URL parameters, and other valid HTML to upload JavaScript, ActiveX, or other executable scripts into an unsuspecting Web site, enabling arbitrary code to run against the client’s browser and the Web server. ¨ =fi k_\ 8[fY\ J\Zli`kp 9lcc\k`e fe :ifjj$J`k\ JZi`gk`e^# j\\ 8J9''$', Xk ]iie/$$lll#VYdWZ#Xdb$YZkcZi$hZXjg^in$ hZXjg^inTodcZ$VhW%%"%*#]iba% =fi 8[fY\Ëj c`jk f] Y\jk giXZk`Z\j ]fi mXc`[Xk`e^ Yifnj\i `eglk# j\\ K\Z_Efk\ 8ik`Zc\ (.,') Xk ]iie/$$lll#VYdWZ#Xdb$\d$icT&,*%'%
XSS works because the Web server accepts non-validated input from the browser, and processes or redisplays the malicious code. Because the server uses the non-validated input to dynamically generate Web pages, the server treats the embedded script as if it came from a trusted source— namely itself—and runs it in the security context of the server’s own pages. So in this vein, a hacker can inject malicious code into a secured (SSL) site, and dupe a consumer into sending their credit card information to their personal server. The original CERT advisory (]iie/$$lll#XZgi#dg\$VYk^hdg^Zh$86"'%%%"%'#]iba) lists the following example code: 16 =G:;2º]iie/$$ZmVbeaZ#Xdb$XdbbZci#X\^4 bnXdbbZci21H8G>EI3bVa^X^djh XdYZ1$H8G>EI3º3 8a^X` ]ZgZ1$63
Changing the HTML character set, inserting database queries into cookies, sending hexadecimal character shell commands, and other Web-server-specific attacks are examples of recent XSS attacks. The first line of defense against cross-site attacks is to update your Web server software. Web server vendors update their products (with hot fixes or service packs) and introduce new tools as the vendors are made aware of vulnerabilities. Examples of such tools are Microsoft’s IIS Lockdown and URLScan Security tools (]iie/$$lll#b^Xgdhd[i#Xdb$iZX]cZi$hZXjg^in$iddah$YZ[Vjai#bhem). In terms of code, Adobe recommends using the following techniques in your CFML: N
Use 8;=:69:G to define a character set in HTML output.
N
Use built-in CFML tags such as X[Vg\jbZci, X[eVgVb, X[fjZgneVgVb! X[egdXeVgVb, X[hl^iX], XÄ[-X[ZahZ, XÅdXVi^dc, X[]ZVYZg, and X[]iba]ZVY.
Browser Validation
N
N
Use built-in functions such as =IBA8dYZ;dgbVi, =IBA:Y^i;dgbVi, JGA:cXdYZY;dgbVi, JGA9ZXdYZ, GZeaVXZA^hi, G:GZeaVXZ, G:GZeaVXZCd8VhZ, HZi:cXdY^c\, Hig^e8G , >hKVa^Y, and >hMBA. Secure Ajax calls with the >h?HDC and KZg^[n8a^Zci function, the hZXjgZ?HDC and application properties, and the hZXjgZ?HDC X[[jcXi^dc tag attribute.
hZXjgZ?HDC N
Properly scope all variables.
N
Escape and replace special characters and tags content in Java.
N
Use the hXg^eiEgdiZXi setting, described in the next section.
K_\ hXg^eiEgdiZXi J\kk`e^ ColdFusion MX 7 introduced the hXg^eiEgdiZXi attribute to protect ColdFusion variables from cross-site scripting attacks. The XSS protection mechanism is a customizable regular expression ColdFusion applies to one or more specified scopes. When enabled, ColdFusion applies the script protection at the beginning of the request during application setting processing. If one of the filtered words (object, embed, script, applet, or meta by default) is submitted as a tag in the specified scopes, ColdFusion replaces all occurrences with the text >ckVa^YIV\. However, the filtered words are allowed as regular text. The hXg^eiEgdiZXi regular expression is defined in the 8gdhhH^iZHXg^eiEViiZgch entry in the (server configuration) or X[TgddiQL:7">C;QX[jh^dcQa^WQcZd" hZXjg^in#mba (J2EE configuration): X[TgddiQa^WQcZd"hZXjg^in#mba
1kVg cVbZ2º8gdhhH^iZHXg^eiEViiZgchº3 1higjXi ineZ2ºXdaY[jh^dc#hZgkZg#8dcÄ\BVeº3 1kVg cVbZ2ºai0QhdW_ZXiqZbWZYqhXg^eiqVeeaZiqbZiVº3 1hig^c\3ai0>ckVa^YIV\1$hig^c\3 1$kVg3 1$higjXi3 1$kVg3
For backward compatibility, ColdFusion 9 script protection is disabled by default. There are three places to enable it: the ColdFusion Administrator, in 6eea^XVi^dc#X[X, and in the 8;6EEA>86I>DC tag: N
The Enable Global Script Protection option in the ColdFusion Administrator Settings window enables XSS protection for the entire server.
N
In 6eea^XVi^dc#X[X, set the hXg^eiEgdiZXi variable in the I=>H scope; for example: i]^h#hXg^eiEgdiZXi2;dgb.
N
To use the 8;6EEA>86I>DC tag, specify the scopes you want to protect in the hXg^eiEgdiZXi attribute.
EFK
cfYXc JZi`gk Gifk\Zk`fe j\kk`e^ Xk k_\ Xggc`ZXk`fe c\m\c%
145
146
CHAPTER
52
Understanding Security
Table 52.1 lists valid script protection values for 6eea^XVi^dc#X[X and the KXYc\ ,)%(
8;6EEA>86I>DC tag attribute.
Values for hXg^eiEgdiZXi
VALUE
DESCRIPTION
CdcZ
Provides no protection for any scopes
6aa
Protects CGI, cookie, form, and URL variables
Comma-delimited list
Protects variables specified in the list
K@G
:fc[=lj`feËj OJJ jZi`gk gifk\Zk`fe ZXe Y\ Xggc`\[ kf Xcc :fc[=lj`fe jZfg\j% ?fn\m\i# [f`e^ jf gcXZ\j X[[`k`feXc gifZ\jj`e^ fm\i_\X[ fe k_\ j\im\i% =fi k_`j i\Xjfe# `] pfl jg\Z`]p X mXcl\ f] 6aa ]fi k_\ hXg^eiEgdiZXi mXi`XYc\ fi Xkki`Ylk\# fi `] pfl \eXYc\ k_`j j\kk`e^ ^cfYXccp `e k_\ 8[d`e`jkiXkfi# fecp k_\ Zfddfecp XkkXZb\[ jZfg\j Xi\ gifk\Zk\[ :>@# Zffb`\# ]fid# Xe[ LIC % :8LK@FE
8ck_fl^_ :fc[=lj`feËj hXg^eiEgdiZXi Xkki`Ylk\ `j X ^i\Xk Ôijk c`e\ f] [\]\ej\# `k [f\j efk gifk\Zk X^X`ejk Xcc ]fidj f] OJJ XkkXZbj% 9\ jli\ kf i\m`\n pfli Xggc`ZXk`feËj jg\Z`ÔZ e\\[j kf [\k\id`e\ n_\k_\i hXg^eiEgdiZXi# hXg^eiEgdiZXi Xe[ Xefk_\i d\k_f[# fi aljk Xefk_\i d\k_f[ Xcfe\ d\\kj k_\ jg\Z`ÔZ j\Zli`kp e\\[j f] pfli Xggc`ZXk`fe%
=fid Xe[ LIC ?XZbj Form and URL hacking are favorites in cross-site attacks. HTML forms are the chief interfaces used to collect data from clients, used for shopping carts, search engines, application and site security, guest books, and more. Because the browser renders the form as cleartext HTML, malicious users can download the form, modify the fields, and then submit the form from another server. URL parameters typically drive dynamic Web pages. URL hacking involves manipulating the URL query string to alter the intended behavior of the rendered Web page. Developers typically evaluate one or more parameters in the URL query string to determine the content of the requested Web page. Perhaps the best example of this is search-engine result pages—changing one of the values in the URL query string usually changes the displayed results. An attack known as SQL injection or SQL poisoning is the most prevalent version of form and URL hacking. Hackers use SQL injection to manipulate databases by submitting additional SQL statements in form fields and URL query strings. The additional SQL is usually something damaging like 9GDE I67A: JhZgh L=:G: &2&. You can imagine the effects of completely removing a Web site’s users table. Since databases are the heart of most Web sites today, form and URL validation is paramount to ensure data integrity and site security. Web servers—hence regular HTML—offer little to no defense against these attacks. Again, it is ColdFusion’s responsibility to protect the data it sends to the back-end systems, and ColdFusion provides several tags and functions that perform the job well.
Browser Validation
MXc`[Xk`fe K\Z_e`hl\j Traditionally, ColdFusion offers the following data validation techniques: N
Decision functions
N
Client- and server-side form validation
N
Variable data-typing with X[Vg\jbZci, X[eVgVb, X[fjZgneVgVb, and X[egdXeVgVb
ColdFusion MX 7 extended the validation techniques by adding more algorithms, options, and functions. This section introduces some of these changes. However, for greater detail see Chapter 13, “Form Data Validation,” in Adobe ColdFusion 9 Web Application Construction Kit, Volume 1: Getting Started. To stop the majority of URL hacks, begin with the same methods highlighted in the “Cross-Site Scripting (XSS)” section. Leverage the CF decision functions to stop SQL injections and similar hacks, specifically the following: >h7^cVgn, >h7ddaZVc, >h9ViZ, >h9ZÄcZY, >h?HDC, >hCj" bZg^X, >hCjbZg^X9ViZ, >hH^beaZKVajZ, >hMBA, AH>h9ViZ, and AH>hCjbZg^X. The >hKVa^Y function combines the functionality of most of the decision functions. In addition to testing regular expressions and numeric ranges, >hKVa^Y can validate any legitimate ColdFusion format, including array, binary, Boolean, component, credit card, date/time/eurodate/U.S. date, email, float/integer/numeric, GUID, query, range, regex, SSN, string, struct, telephone, URL, UUID, variable name, XML, and U.S. ZIP code. K@G
Lj\ >hKVa^Y Xj k_\ ]leZk`fe \hl`mXc\ek f] k_\ 8;E6G6B kX^%
ColdFusion 9 extends the built-in client-and server-side form validation. You can create XML and Flash forms with extended validation algorithms. N
The 8;;DGB tag provides client-side JavaScript for form-field validating in the browser.
N
The 8;>CEJI tag provides the bVh` and kVa^YViZVi attributes. The bVh` attribute allows developers to create character patterns to control user data input in text fields. The kVa^YViZVi attribute specifies where data validation occurs. It accepts one or more of the following values in a comma-separated list: dc7ajg, where validation occurs in the browser when the form field loses focus; dcHjWb^i, where validation occurs in the browser before the form is submitted; and dcHZgkZg, where validation occurs on the server.
For server-side form validation, ColdFusion MX 7 extended the existing hidden form-field validation support with an additional 12 validation rules. It also changed the special rule identifiers to suffixes beginning with TX[, but continues to support the original syntax for backward compatibility. The dcHZgkZg value for the 8;>CEJI kVa^YViZVi attribute produces the same server-side validation rules as the hidden form-field method.
147
148
CHAPTER
52
Understanding Security
K@G
9fk_ kVa^YViZVi2dcHZgkZg Xe[ _`[[\e ]fid Ô\c[j gifm`[\ k_\ jXd\ mXc`[Xk`fe ilc\j% ?fn\m\i# lj\ _`[[\e ]fid Ô\c[j `] pfl nXek kf Xggcp dlck`gc\ mXc`[Xk`fe ilc\j kf X j`e^c\ ]fid Ô\c[# fi `] pfl nXek kf gifm`[\ j\im\i$j`[\ mXc`[Xk`fe ]fi i\^lcXi ]fid Ô\c[j%
Client- and server-side validation each has its pros and cons, but they share one common fatal flaw: They rely on code in the client. 8;;DGB (and related tags) generate form fields and the JavaScript code that evaluates them in the browser. ColdFusion’s server-side validation relies on hidden form fields for the validation rules. Savvy hackers will save the rendered HTML forms and remove the JavaScript and hidden form fields, thus bypassing all validation. K@G
8 e`Z\ d\k_f[ f] gifk\Zk`fe X^X`ejk lj\i$df[`Ô\[ ]fid jlYd`kkXcj `j kf Zf[\ Zfe[`k`feXc cf^`Z k_Xk ZfdgXi\j k_\ 8#=IIET =DHI Xe[ 8#=IIETG:;:G:G mXcl\j% =fi \oXdgc\1 1XÄ[ CDI ;^cYCd8VhZ8#=IIET=DHI! 8#=IIETG:;:G:G3 >ckVa^Y ;dgb hjWb^iiVa 1XÅdXVi^dc jga2ºWnZWnZ#X[bº3 1$XÄ[3
@] k_`j Zf[\ i\kliej ]Xcj\# k_\e pfl befn k_\ ]fid nXj jlYd`kk\[ ]ifd Xe \ok\ieXc j\im\i%
A combination of client- and server-side validation is the best protection. However, be sure to also code your own CFML to perform data typing before sending values to back-end systems. Use proper variable scoping and tags such as X[Vg\jbZci, X[eVgVb, X[egdXeVgVb, and X[fjZgneVgVb to ensure that the correct variable exists and is of the correct type. Use ^["ZahZ and hl^iX]"XVhZ blocks to apply conditional logic and set default values. Working with validation techniques requires more effort on your part—but considering the potential aftermath of a hack, an ounce of prevention...
=`c\ LgcfX[j The attacks described in this section center around affecting your site by directly manipulating your code and data. Allowing users to upload files directly to your Web server potentially exposes your entire system and network to harm. Electronic libraries and head-hunter sites are examples that typically allow file uploads. If unchecked, hackers can freely upload viruses, worms, Trojan horses, and so on, to your Web server, which can spread to your server farm, and eventually cripple your entire network. The best defense against harmful file uploads is to avoid uploads altogether. If this feature is a vital part of your application’s functionality, however, use antivirus software to stop the infection of worms and Trojan horses. Limit upload features to authenticated users. Only allow uploads of certain file types and lengths, and to a separate physical server running antivirus software. ColdFusion is not an antivirus program, but you can write CFML that controls the destination, MIME type, and size restrictions and that sets the attributes of uploaded files and adjust the Maximum Size of Post Data value on the ColdFusion 9 Administrator Settings screen. You can also code your own security routine in CFML that will limit uploading to authenticated users, as shown in Listing 52.3.
Browser Validation
C`jk`e^ ,)%*
jeadVYZg#X[b —Limiting
File Upload to Authorized Users
1X[hZii^c\ ZcVWaZX[djiejidcan2ºnZhº3 1""" CVbZ d[ ÄaZ/ jeadVYZg#X[b 9ZhXg^ei^dc d[ i]Z hXg^ei/ 9^heaVnh Xdd`^Zh kVajZh XVeijgZY [gdb dcZ h^iZ VcY hZi ^c i]Z JGA d[ i]Z adXVa h^iZ# 6ji]dg cVbZ VcY Z"bV^a/ HVg\Z hVg\Z5hVg\ZlVn#Xdb lll#hVg\ZlVn#Xdb$Wad\$ 9ViZ XgZViZY/ ;ZWgjVgn .! '%%* 9ViZ bdY^ÄZY/ BVgX] &.! '%&% """3 1X[hZii^c\ ZcVWaZX[djiejidcan2ºcdº3 19D8INE: =IBA EJ7A>8 "$$L(8$$9I9 =IBA )#% IgVch^i^dcVa$$:C3 1]iba3 1]ZVY3 1i^iaZ38daY;jh^dc . >bV\Z JeadVY IZhi1$i^iaZ3 1$]ZVY3 1WdYn3 1]'38daY;jh^dc . >bV\Z JeadVYZg1$]'3 1""" 8]ZX` jhZg¼h Vji]dg^oVi^dc id jeadVY# """3 1XÄ[ CDI >hJhZg>cGdaZ¹ejWa^h]Zgº3 1XÄcXajYZ iZbeaViZ2ºad\^c[dgb#X[bº3 1V ]gZ[2º^cYZm#X[bº37VX` id ^cYZm1$V31X[VWdgi3 1X[ZahZ^[ >h9ZÄcZY¹;DGB#jeadVYº3 1X[eVgVb cVbZ2ºkVg^VWaZh#jeadVYY^gº YZ[Vjai2º_/Qdi]ZghZgkZgQ^bV\Zhº3 1X[ign3 1""" GZhig^Xi jeadVY h^oZ# """3 1XÄ[ 8#8DCI:CITA:C9 Vh i]Z gddi jhZg# Kf Z_Xe^\ k_\ iffk lj\i# j\\ k\Z_ efk\ bY+')+,0# :fc[=lj`fe /1 ?fn kf :_Xe^\ k_\ Iffk 8[d`e`jkiXkfi Lj\ieXd\# Xk ]iie/$$lll# VYdWZ#Xdb$\d$`W)%')*.%
4. In the User RDS and Administrator Access section, do the following: N
To grant the user RDS permissions, check the box for Allow RDS Access. If the Separate User Name and Password Authentication type is not enabled for RDS authentication, you will receive an alert message (Figure 53.5).
=`^li\ ,*%, Separate User name and Password Authentication required for userbased RDS access.
N
To grant the user access to Administrator resources, check the box for Allow Administrative Access. If the Separate User Name and Password Authentication type is not enabled for Administrator authentication, you will receive an alert message (Figure 53.6).
=`^li\ ,*%Separate User name and Password Authentication required for user-based Administrator access.
N
Decide whether to grant Administrator console and API access, or API access only and select the radio button next to the appropriate option.
N
In the Prohibited Roles list, select the roles that you want to grant to the user account and click the left-pointing arrows button (c, and kZg^[n8a^Zci security functions.
J\Zli`kp KX^j Xe[ =leZk`fej As previously mentioned, ColdFusion includes tags and functions with which to implement security and access control. Table 54.1 describes the ColdFusion security tags and functions. KXYc\ ,+%(
ColdFusion Security Tags and Functions
TAG OR FUNCTION
DESCRIPTION
1XÅd\^c3
Provides a container for user authentication code. Used with the 1XÅd\^cjhZg3 tag to validate a user login against an LDAP, database, or other user repository.
1XÅd\^cjhZg3
Identifies the authenticated user to ColdFusion by specifying the user’s ID, password, and gdaZh. Requires the cVbZ, eVhhldgY, and gdaZh attributes. Specify a comma-delimited list to the gdaZh attribute. ColdFusion evaluates white space in this attribute, so be careful not to add spaces after commas.
1XÅd\dji3
Logs the current authenticated user out of ColdFusion by completely removing the user’s authenticated ID (session) and roles. When this tag is not used, ColdFusion automatically logs users out when their sessions time out.
1X[[jcXi^dc3
The gdaZh attribute restricts function execution to authenticated users in the specified roles. The hZXjgZ?HDC attribute determines whether to prepend a security prefix to JSON-formatted return values. The kZg^[n8a^Zci attribute determines whether to require remote function calls in ColdFusion Ajax applications to include an encrypted security token.
1X[ciVji]Zci^XViZ3
Authenticates a username against the Windows domain in which the ColdFusion server is running. This tag can optionally retrieve the authenticated user’s group memberships as well. This tag was added in ColdFusion MX 7.
c6cnGdaZ
Returns true if the authenticated user is a member of any role listed in the string passed to the function.
>hJhZg>cGdaZ
Returns igjZ if the authenticated user is a member of the specified roles. Use a comma-delimited list to check multiple role assignments.
>hJhZgAd\\ZY>c
Returns igjZ if the user is authenticated.
165
166
CHAPTER
54
ColdFusion Security Options
EFK< 1X[ciVji]Zci^XViZ3 i\hl`i\j pfl kf ile k_\ :fc[=lj`fe j\im`Z\ Xj X lj\i n`k_ gi`m`c\^\j kf Xlk_\ek`ZXk\ fk_\i lj\ij `e k_\
jg\Z`Ô\[ N`e[fnj [fdX`e% @k Xcjf i\hl`i\j k_\ :fc[=lj`fe j\im\i kf ile fe X N`e[fnj [fdX`e n`k_ e\knfib XZZ\jj kf X gi`dXip [fdX`e Zfekifcc\i G;: ]fi N`e[fnj EK+ [fdX`ej fi G;: \dlcXkfi N`e[fnj 8Zk`m\ ;`i\Zkfip [fdX`ej%
8lk_\ek`ZXk`e^ n`k_ 1XÅd\^c3 Code all of your authentication logic between 1XÅd\^c3 tags—including database username/ password lookups, Windows authentication, LDAP logins, and so forth. The 1XÅd\^c3 tag creates a container for storing user security information—the 8;ADC scope. This scope contains two variables: 8;ADC#cVbZ and 8;ADC#eVhhldgY. These two variables are populated with a user’s login ID and password when any of the following occurs: K@G
8lk_\ek`ZXk`fe cf^`Z Y\kn\\e 1XÅd\^c3 kX^j ZXe Xcjf Y\ ZXccj kf \ok\ieXc Zfdgfe\ekj# Xe[ efk aljk `e$c`e\ :=DC% N
A form is submitted containing input fields with the special _TjhZgcVbZ and _TeVhhldgY names. For example: 1^ceji ineZ2ºiZmiº cVbZ2º_TjhZgcVbZº3 1^ceji ineZ2ºeVhhldgYº cVbZ2º_TeVhhldgYº3
N
An Adobe Flash Remoting \ViZlVn8dccZXi^dc object is sent containing the hZi8gZYZci^Vah method.
K@G
=fi Xe \oXdgc\ f] _fn kf Xlk_\ek`ZXk\ m`X =cXj_ I\dfk`e^# j\\ 8[fY\ K\Z_Efk\ (/-/+# È?fn kf gXjj cf^`e Zi\[\ek`Xcj kf XÅd\^c m`X =cXj_ I\dfk`e^É Xk ]iie/$$lll#VYdWZ#Xdb$\d$icT&-+-)% N
A request contains an Authorization Header with a username and password sent via HTTP Basic authentication.
N
A request contains an Authorization Header with a hashed username and password sent via Digest or NTLM authentication. In this case, 8;ADC#cVbZ contains the username sent by the Web server, but 8;ADC#eVhhldgY is set to an empty string.
:8LK@FE
Lj\ieXd\ Xe[ gXjjnfi[ Xi\ j\ek `e Zc\Xi k\ok lj`e^ X j`dgc\ cf^`e ]fid% =cXj_ I\dfk`e^ j\e[j k_\ lj\ieXd\&gXjjnfi[ fm\i k_\ Y`eXip$\eZf[\[ 8D= 8Zk`fe D\jjX^\ =fidXk gifkfZfc% ?KKG 9Xj`Z Xlk_\ek`ZXk`fe j\e[j k_\ lj\ieXd\ Xe[ gXjjnfi[ `e X 9Xj\-+$\eZf[\[ jki`e^ n`k_ \XZ_ i\hl\jk% :fej`[\i lj`e^ JJC ?KKGJ kf j\Zli\ k_\ lj\ieXd\ Xe[ gXjjnfi[ n_\e Xlk_\ek`$ ZXk`e^ n`k_ k_\j\ d\k_f[j%
The 1XÅd\^c3 tag accepts three optional attributes: N
>YaZI^bZdji.
The maximum time interval for inactivity (the period between page requests) before logging out the user. The default value is 1800 seconds (30 minutes). This attribute is ignored if the ad\^cHidgV\Z attribute is set to HZhh^dc in the 1X[Veea^XVi^dc3 tag or 6eea^XVi^dc#X[X.
ColdFusion Security Framework
N
6eea^XVi^dcId`Zc.
An application-specific identifier used to restrict the 8;ADC scope to the current application. This defaults to the current application name—specified in the 1X[Veea^XVi^dc3 tag or with the I=>H#cVbZ variable in 6eea^XVi^dc#X[X —and prevents cross-application logins. ColdFusion allows you to specify the same Veea^XVi^dcId`Zc value for multiple applications.
EFK
O6I>DCT Veea^XVi^dccVbZ2 _fn\m\i# :fc[=lj`fe Xccfnj leeXd\[ Xggc`ZXk`fej ]fi A)hJhZgAd\\ZY>c function returns true. The hJhZg>cGdaZ function checks the provided role against the list of roles specified in 1XÅd\^cjhZg3. K@G
@] N\Y j\im\i j\Zli`kp `j lj\[ `ejk\X[ f] :fc[=lj`fe j\Zli`kp 8;ADC # hJhZg>cGdaZh ]leZk`fe i\hl`i\j 1XÅd\^cjhZg3%
Jkfi`e^ Cf^`e @e]fidXk`fe Login credentials are stored either in a cookie or in the HZhh^dc scope, as determined by the Ad\^cHidgV\Z value as either an 6eea^XVi^dc#X[X initialization variable or in the 1X[Veea^XVi^dc3 attribute. By default, 1XÅd\^c3 sets a non-persistent cookie in the user’s browser, called X[Vji]dg^oVi^dcT Veea^XVi^dcCVbZ. The cookie value is a Base64-encoded string containing the user ID, password, and application name. This in-memory cookie is not written to disk (for example, the Xdd`^Zh#imi file) and is destroyed when the browser closes. Because ColdFusion sends this cookie with every request, users must allow in-memory cookies in their browsers. If the browser disables cookies, then the effect of the 1XÅd\^cjhZg3 tag exists only for the current page request. In this scenario, ColdFusion allows you to code the 1XÅd\^cjhZg3 outside of the 1XÅd\^c3 tag in every template you want to secure, in order to persist the login information across page requests. When storing login information in the HZhh^dc scope, ColdFusion stores the Base64-encoded user ID, password, and application name in the H:HH>DC#X[Vji]dg^oVi^dc variable. ColdFusion stores this variable in its internal memory space and uses the browser’s session cookies (8;>9 and 8;ID@:C , or ?H:HH>DC>9) for user identification. This is more secure than using cookies for login
167
168
CHAPTER
54
ColdFusion Security Options
storage because ColdFusion does not pass H:HH>DC#X[Vji]dg^oVi^dc with every page request. The user’s login and session share the same timeout value—and ColdFusion ignores the >YaZI^bZdji 1XÅd\^c3 attribute. EFK
DC#X[Vji]dg^oV" i^dc cf^`e mXi`XYc\ `j XmX`cXYc\ kf Xcc d\dY\ij `e X j\im\i Zcljk\i%
9\jk GiXZk`Z\1 :fc[=lj`fe J\jj`fej Xe[ 8;ADC Session-scoped variables are held in ColdFusion memory space. Storing the 8;ADC authorization variable (H:HH>DC#X[Vji]Zci^XViZ) in the HZhh^dc scope (Ad\^cHidgV\Z2HZhh^dc) will persist the value for the duration of the user’s session. If the user closes the browser without logging out with 8;AD9 and 8;ID@:C or ?H:HH>DC>9) as the authenticated user, that user can impersonate the previously authenticated user. ColdFusion identifies browser sessions by cookies and URL parameters. A ColdFusion Session ID comprises the 8;>9, 8;ID@:C, and Application name (Veea^XVi^dcCVbZT8;>9T8;ID@:C). When J2EE Sessions are enabled, the Session ID is the ?H:HH>DC>9 value. A ColdFusion session can be impersonated by passing existing Session ID values on the URL or in cookies. The following are best-practice steps to prevent session impersonation: N
Use the kZg^[n8a^Zci function and 6eea^XVi^dc#X[X$1X[Veea^XVi^dc3 attribute to force ColdFusion to require the encrypted security token for ColdFusion Ajax client requests.
N
Enable J2EE session management and use ?H:HH>DC>9: N
?H:HH>DC>9
is a randomly generated, alphanumeric string created as a non-persistent
cookie. N
N
Use DC#X[Vji]Zci^XViZ).
For ColdFusion session management: N
Use a UUID for 8;ID@:C. Enable UUID for 8;ID@:C in the ColdFusion Administrator Settings page.
ColdFusion Security Framework
N
Ensure CFID and CFTOKEN are created as non-persistent values. See Adobe TechNote 17915 at ]iie/$$lll#VYdWZ#Xdb$\d$icT&,.&*.
N
Do not allow Session variables to pass on the URL. These values are not browser specific like cookies.
N
When logging out the user, ensure that 1XÅd\dji3 is called as well as HigjXi8aZVgHZhh^dc. HigjXi8aZVgHZhh^dc clears all session variables except the H:HH>DC>9 and H:HH>DC#X[Vji]Zci^XViZ values.
N
Use the DcHZhh^dcHiVgi method in the 6eea^XVi^dc#X[X to clear any existing H:HH>DC>9 values (from URL or cookie).
N
Call 1XÅd\dji3 in the DcHZhh^dc:cY method to ensure the logged-in user is logged out when the session ends.
N
When creating user sessions inspect 8#=IIETG:;:G:G to ensure the request is coming from within the application.
Cf^^`e^ Flk There are several ways to log out users and remove their login information from ColdFusion. The primary method is to use the 1XÅd\dji3 tag. ColdFusion MX did a poor job of destroying session information after a user logged out. Table 54.2 lists the circumstances in which ColdFusion logs out the current user and destroys the 1XÅd\^cjhZg3 authentication credentials. KXYc\ ,+%)
ColdFusion User Logout
DESCRIPTION
Ad\^cHidgV\Z28dd`^Z Ad\^cHidgV\Z2HZhh^dc
Application fires 1XÅd\dji3
x
x
The 1XÅd\^c3 >YaZI^bZdji value is reached
x
N/A
The user closes all browser windows
x
N/A
The ColdFusion session ends
N/A
x
:8LK@FE 1XÅd\dji3 [f\j efk Zc\Xi k_\ cf^`e `e]fidXk`fe `] pfl Xlk_\ek`ZXk\ lj\ij m`X N\Y j\im\i j\Zli`kp fi k_\ ?KKG 8lk_fi`qXk`fe
_\X[\i% K_\j\ j\Zli`kp gXiX[`^dj Zfek`el\ kf j\e[ Xlk_\ek`ZXk`fe `e]fidXk`fe kf :fc[=lj`fe lek`c Xcc Yifnj\i n`e[fnj Xi\ Zcfj\[% K_\i\]fi\# lek`c Xcc Yifnj\i n`e[fnj Xi\ Zcfj\[# k_\ 8;ADC jZfg\ dXp g\ij`jk Y\pfe[ lj\i cf^flk# gifm`[`e^ X n`e$ [fn f] fggfikle`kp ]fi Xefk_\i lj\i kf `dg\ijfeXk\ k_\ Ôijk lj\i%
Executing 1XÅd\dji3 when using Ad\^cHidgV\Z2HZhh^dc removes the H:HH>DC#X[Vji]dg^oVi^dc variable from the HZhh^dc scope, but does not end the current user’s session. Therefore, if you want to log the user out and completely clear his or her session, you must code logic that calls 1XÅd\dji3 and HigjXi8aZVgHZhh^dc: 1XÄ[ >h9ZÄcZY»JGA#Ad\dji¼ VcY JGA#Ad\dji3 1XÅd\dji3 1X[hZi HigjXi8aZVgHZhh^dc3 1$XÄ[3
169
170
CHAPTER
54
ColdFusion Security Options
K@G
:Xcc`e^ HigjXi8aZVgHZhh^dc n`cc efk ^\e\iXk\ X e\n j\jj`fe `[ Ylk `k n`cc Zfdgc\k\cp \dgkp k_\ J<JJ@FE jkilZkli\%
9Xj`Z :fc[=lj`fe Cf^`e h9ZÄcZY¹G:FJ:HI#WVYad\^cº31heVc hinaZ2ºXdadg/ gZYº3Ndjg ad\^c ^c[dgbVi^dc lVh ^ckVa^Y1$heVc31$XÄ[3 1""" JhZ X[[dgb id egdk^YZ Xa^Zci"h^YZ _VkVhXg^ei kVa^YVi^dc dc i]Z jhZg cVbZ [dgb ÄZaY# """3
171
172
CHAPTER
54
C`jk`e^ ,+%)
ColdFusion Security Options
(continued)
1X[[dgb VXi^dc2º^cYZm#X[bº bZi]dY2ºedhiº3 1iVWaZ WdgYZg2º%º3 1ig3 1iY3JhZg CVbZ/1$iY3 1iY31XÄceji ineZ2ºiZmiº cVbZ2º_TjhZgcVbZº bZhhV\Z2ºNdj bjhi ZciZg V jhZg cVbZº gZfj^gZY2ºnZhº31$iY3 1$ig3 1ig3 1iY3EVhhldgY/1$iY3 1iY31XÄceji ineZ2ºeVhhldgYº cVbZ2º_TeVhhldgYº bZhhV\Z2ºNdj bjhi ZciZg V eVhhldgYº gZfj^gZY2ºnZhº31$iY3 1$ig3 1ig3 1iY3cWhe01$iY3 1iY31^ceji ineZ2ºgZhZiº3 q 1^ceji ineZ2ºhjWb^iº cVbZ2ºad\dcº kVajZ2ºAd\^cº31$iY3 1$ig3 1$iVWaZ3 1$X[[dgb3 1$WdYn3 1$]iba3
K@G
K_\ _TjhZgcVbZ Xe[ _TeVhhldgY mXcl\j Xi\ jlYd`kk\[ Xj Zc\Xi k\ok% =fi ^i\Xk\i j\Zli`kp# Zfej`[\i lj`e^ JJC kf gi\m\ek \Xm\j[ifgg`e^ XkkXZbj%
The ad\^c;dgb#X[b template contains the actual form that submits the username and password. These are processed by the 6eea^XVi^dc#X[b when the form is submitted. The code in 6eea^XVi^dc #X[b will allow processing to continue with ^cYZm#X[b if authentication is successful; otherwise, the login form will redisplay. C`jk`e^ ,+%*
^cYZm#X[b —Securing
a Template with hJhZg>cGdaZ
1X[h^aZci3 1""" ;^aZ CVbZ/ ^cYZm#X[b 9ZhXg^ei^dc/ >cYZm eV\Z hZXjgZY Wn 1XÅd\^c3 ^c i]Z 6eea^XVi^dc#X[b# I]^h eV\Z Vahd h]dlh ]dl id jhZ i]Z 8daY;jh^dc hZXjg^in [jcXi^dch/ hJhZg>cGdaZ# 6hhjbei^dch/ CdcZ 6ji]dg cVbZ VcY Z"bV^a/ HVg\Z hVg\Z5hVg\ZlVn#Xdb 9ViZ 8gZViZY/ ?jan ')! '%%' 8]Vc\Z Ad\/ JeYViZY ;ZWgjVgn '%! '%%* """3 1$X[h^aZci3 1YdXineZ ]iba ejWa^X ¹"$$l(X$$YiY ]iba )#%& igVch^i^dcVa$$Zcº3 1]iba3 1WdYn3 1""" JhZ i]Z hJhZg>cGdaZ [jcXi^dc id VYY XdcY^i^dcVa ad\^X WVhZY dc i]Z jhZg¼h \gdje bZbWZgh]^e gdaZ# """3 1XÄ[ >hJhZg>cGdaZ¹VYb^chº3 1e37VhZY dc ndjg ad\^c >9! ndj VgZ eZgb^iiZY id VXXZhh i]^h hZXi^dc d[ i]Z h^iZ#1Wg $3
ColdFusion Login Wizard Extension
C`jk`e^ ,+%*
(continued)
EaZVhZ egdXZZY id i]Z 1V ]gZ[2º^cYZm#X[bº i^iaZ2ºI]^h a^c` ^h [dg YZbdchigVi^dc ejgedhZh dcanº36Yb^c^higVidg¼h hZXi^dc1$V3#1$e3 1""" 9^heaVn i]Z ad\ dji a^c`# """3 1e31V ]gZ[2º^cYZm#X[b4ad\dji2nZhº3Ad\ Dji1$dc31$e3 1$XÄ[3 1$WdYn3 1$]iba3
:fc[=lj`fe Cf^`e N`qXi[ l`[\ _\cg dXelXc Xk ]iie/$$a^kZYdXh#VYdWZ#Xdb$XdaY[jh^dc$-$]ibaYdXh$ Vee;gVbZldg`T&*#]iba&&.&)*)%
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: N
The 6eea^XVi^dc#X[X contains no initialization variables, including application name, or the like. You should code these variables to strengthen your security paradigm.
Ad\^cHidgV\Z, HZhh^dcBVcV\ZbZci, HZhh^dcI^bZdji, HZi8a^Zci8dd`^Zh,
N
Consider changing the h^beaZ6ji] authentication method to perform a database query using the submitted username and password instead of a simple string comparison. Use the =Vh] function to strengthen the security of passwords in the database. See Chapter 52 for more information on the ColdFusion 9 =Vh] function.
N
The authentication methods contain simplified code and may not work without modification. For example, the LDAP code queries for an attribute named ¹gdaZhº, which is probably not valid for most LDAP servers.
N
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.
N
All authenticated users are granted a single role: user. Modify this hard-coded 1XÅd\^" cjhZg3 value in the eZg[dgbAd\^c method to dynamically accept roles returned from the authentication methods.
N
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 1X[]ZVYZg3 tag in the eZg[dgbAd\^c method.
N
The wizard creates a default error message for login failures, but it does not create code for handling any exceptions, such as domain controller access failures or LDAP failure codes.
K@G
:_ffj`e^ k_\ i`^_k cf^`e Z_Xcc\e^\ `j `dgfikXek% J\c\Zk 9ifnj\i ;`Xcf^ 9fo `] pfl Xi\ `ek\^iXk`e^ n`k_ N\Y j\im\i Xlk_\ek`ZXk`fe# fi Z_fj\ EK ;fdX`e Xj k_\ Xlk_\ek`ZXk`fe kpg\% Lj\ X :fc[=lj`fe cf^`e gX^\ ]fi [XkXYXj\ Xe[ C;8G cf^`ej# Y\ZXlj\ X [XkXYXj\ Xe[ C;8G nfeËk Y\ XYc\ kf mXc`[Xk\ k_\ 9Xj`Z I\Xcd f] k_\ NNN 8lk_\ek`ZXk`fe _\X[\i gXjj\[ Yp k_\ 9ifnj\i [`Xcf^ Yfo%
ColdFusion Login Wizard Extension
:fc[=lj`fe Cf^`e N`qXi[ H#cVbZ variable, to set the application name. The bbTl^oVgYT^cXajYZ#X[b in Listing 54.6 records the parameters entered into the wizard fields and passes them to the bbT l^oVgYTVji]Zci^XViZ#X[X. The h^beaZVji] and aYVeVji] methods have been removed from the bbTl^oVgYTVji]Zci^XViZ#X[X in Listing 54.7. The ciVji] method has been modified to return the authentication structure returned from the 1X[ciVji]Zci^XViZ3, which is used to log in the user. Table 54.3 lists the 1X[ciVji]Zci^XViZ3 attributes; Table 54.4 lists the fields in the returned structure. K@G
@] pflËi\ ]Xd`c`Xi n`k_ g\i]fid`e^ Xlk_\ek`ZXk`fe Xe[ Xlk_fi`qXk`fe `e pfli 6eea^XVi^dc#X[b# dfm\ k_\ 1XÅd\^c3 Zfe$ kX`e\i `ekf k_\ DcGZfjZhiHiVgi d\k_f[ f] k_\ 6eea^XVi^dc#X[X%
KXYc\ ,+%* 1X[ciVji]Zci^XViZ3 Attributes ATTRIBUTE
DESCRIPTION
REQUIRED
jhZgcVbZ
A username to authenticate against the specified domain.
Yes
eVhhldgY
The password for the specified username.
Yes
YdbV^c
Windows domain to authenticate against. ColdFusion must be Yes running on a server within the specified domain.
gZhjai
Variable name for the return structure. Default value is X[Vji]Zci^XViZ.
No
a^hiO6G9 8D9:/ :C9 """3
C`jk`e^ ,+%.
bbTl^oVgYTVji]Zci^XViZ#X[X —ColdFusion
Wizard’s Authentication File
1""" ;^aZ cVbZ/ bbTl^oVgYTVji]Zci^XViZ#X[X 9ZhXg^ei^dc/ BdY^ÄZY 8daY;jh^dc Ad\^c L^oVgY iZbeaViZ i]Vi eZg[dgbh jhZg Vji]Zci^XVi^dc VcY ad\^c# 6hhjbei^dch/ I]^h iZbeaViZ dcan eZg[dgbh L^cYdlh Vji]Zci^XVi^dc "" Vaa di]Zg Vji]Zci^XVi^dc bZi]dYh VgZ gZbdkZY# 6ji]dg cVbZ VcY Z"bV^a/ HVg\Z hVg\Z5hVg\ZlVn#Xdb 9ViZ 8gZViZY/ ;ZWgjVgn ''! '%%* """3
181
182
CHAPTER
54
C`jk`e^ ,+%.
ColdFusion Security Options
(continued)
1X[XdbedcZci3 1"""" $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$"""3 1"""" CI 9dbV^c 6ji]Zci^XVi^dc """3 1"""" $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$"""3 1X[[jcXi^dc cVbZ2ºciVji]º VXXZhh2ºeg^kViZº djieji2º[VahZº gZijgcineZ2ºhigjXiº ]^ci2º6ji]Zci^XViZ V\V^chi V CI YdbV^cº3 1X[Vg\jbZci cVbZ2ºcjhZgcVbZº gZfj^gZY2ºigjZº ]^ci2ºI]Z jhZgcVbZº3 1X[Vg\jbZci cVbZ2ºceVhhldgYº gZfj^gZY2ºigjZº ]^ci2ºI]Z eVhhldgYº3 1X[Vg\jbZci cVbZ2ºcYdbV^cº gZfj^gZY2ºigjZº ]^ci2ºI]Z YdbV^c id Vji]Zci^XViZ V\V^chiº3 1""" BdY^[n i]Z 1X[ciVji]Zci^XViZ3 Wn hZii^c\ a^hi\gdjeh2nZh """3 1X[ciVji]Zci^XViZ jhZgcVbZ2ºVg\jbZcih#cjhZgcVbZº eVhhldgY2ºVg\jbZcih#ceVhhldgYº YdbV^c2ºVg\jbZcih#cYdbV^cº gZhjai2ºVji]Zci^XViZYº a^hi\gdjeh2ºnZhº3 1X[gZijgc Vji]Zci^XViZY3 1$X[[jcXi^dc3 1"""" $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$"""3 1""" I]^h bZi]dY eZg[dgbh i]Z 1XÅd\^c3 XVaa VcY ^c ijgc """3 1""" XVaah i]Z VXijVa Vji]Zci^XVi^dc bZi]dY """3 1"""" $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$"""3 1X[[jcXi^dc cVbZ2ºeZg[dgbad\^cº VXXZhh2ºejWa^Xº djieji2ºigjZº ]^ci2ºAd\ V jhZg ^c jh^c\ Z^i]Zg CI Vji]Zci^XVi^dc#º3 1X[Vg\jbZci cVbZ2ºVg\hº ineZ2ºhigjXiº gZfj^gZY2ºigjZº ]^ci2ºI]ZhZ VgZ i]Z eVgVbZiZgh hZije Wn i]Z Ad\^c L^oVgYº3 1XÅd\^c3 1XÄ[ CDI >h9ZÄcZY¹XÅd\^cº3 1XÄcXajYZ iZbeaViZ2ºVg\h#ad\^c[dgbº31X[VWdgi3 1X[ZahZ3 1X[ign3 1XÄckd`Z bZi]dY2ºciVji]º gZijgckVg^VWaZ2ºgZhjaiº cjhZgcVbZ2ºXÅd\^c#cVbZº ceVhhldgY2ºXÅd\^c#eVhhldgYº cYdbV^c2ºVg\h#YdbV^cº 3 1X[XViX]3 1X[hZi ZggdgBZhhV\Z 2 ¹Ndjg ad\^c ^c[dgbVi^dc ^h cdi kVa^Y#1Wg3EaZVhZ Ign V\V^cº3 1XÄcXajYZ iZbeaViZ2ºVg\h#ad\^c[dgbº31X[VWdgi3 1$X[XViX]3 1$X[ign3 1$XÄ[3 1""" kVa^YViZ ^[ i]Z jhZg ^h Vji]Zci^XViZY """3 1XÄ[ gZhjai#Vji] Zf ¹N:Hº3 1""" ^[ Vji]Zci^XViZY """3 1XÅd\^cjhZg cVbZ2ºXÅd\^c#cVbZº eVhhldgY2ºXÅd\^c#eVhhldgYº gdaZh2ºgZhjai#\gdjehº3 1X[ZahZ3 1""" ^[ cdi Vji]Zci^XViZY! gZijgc id ad\^c [dgb l^i] Vc Zggdg bZhhV\Z """3 1X[hZi ZggdgBZhhV\Z 2 ¹Ndjg ad\^c ^c[dgbVi^dc ^h cdi kVa^Y#1Wg3EaZVhZ Ign V\V^cº3 1XÄcXajYZ iZbeaViZ2ºVg\h#ad\^c[dgbº31X[VWdgi3 1$XÄ[3
ColdFusion Login Wizard Extension
C`jk`e^ ,+%.
(continued)
1$XÅd\^c3 1$X[[jcXi^dc3 1"""" $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$"""3 1""" Ad\dji """3 1"""" $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$"""3 1X[[jcXi^dc cVbZ2ºad\djiº VXXZhh2ºgZbdiZº djieji2ºigjZº ]^ci2ºAd\ i]Z jhZg dji#º3 1X[Vg\jbZci cVbZ2ºad\^cineZº ineZ2ºhig^c\º gZfj^gZY2ºnZhº ]^ci2ºI]Z ad\^c ineZ jhZY id ad\^c#º3 1XÄ[ ^h9ZÄcZY¹[dgb#ad\djiº3 1XÅd\dji3 1XÄ[ Vg\jbZcih#ad\^cineZ Zf ¹X]VaaZc\Zº3 1X[hZi [dd 2 XadhZ7gdlhZg3 1X[ZahZ3 1""" gZeaVXZ i]^h JGA id V eV\Z ad\\ZY dji jhZgh h]djaY hZZ """3 1XÅdXVi^dc jga2º]iie/$$lll#6YdWZ#Xdbº3 1$XÄ[3 1$XÄ[3 1$X[[jcXi^dc3 1"""" $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$"""3 1""" 8adhZ 7gdlhZg """3 1""" Id ZchjgZ i]Z ]ZVYZg Vji]Zci^XVi^dc ^c[dgbVi^dc """3 1""" ]Vh WZZc i]djgdj\]an Åjh]ZY i]Z WgdlhZg h]djaY WZ XadhZY """3 1"""" $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$"""3 1X[[jcXi^dc cVbZ2ºXadhZ7gdlhZgº VXXZhh2ºejWa^Xº djieji2ºigjZº ]^ci2º8adhZ i]Z WgdlhZg id XaZVg i]Z ]ZVYZg ^c[dgbVi^dc#º3 1hXg^ei aVc\jV\Z2º_VkVhXg^eiº3 ^[cVk^\Vidg#VeeCVbZ 22 ¹B^Xgdhd[i >ciZgcZi :meadgZgº p VaZgi¹I]Z WgdlhZg l^aa cdl XadhZ id XdbeaZiZ i]Z ad\dji#º0 l^cYdl#XadhZ0 r ^[cVk^\Vidg#VeeCVbZ 22 ¹CZihXVeZº p VaZgi¹Id XdbeaZiZ i]Z ad\dji ndj bjhi XadhZ i]^h WgdlhZg#º0 r 1$hXg^ei3 1$X[[jcXi^dc3 1$X[XdbedcZci3
183
This page intentionally left blank
:?8GKC;Q_gjc"lZW#mba Ôc\% I\d\dY\i# k_`j `j AXmX# jf Xcc j\kk`e^j Xi\ ZXj\$j\ej`k`m\
Creating and Securing Applications Using Sandboxes
=`^li\ ,,%* Create a directory named 7aVX`Wdm in your Web root.
<eXYc`e^ JXe[Yfo J\Zli`kp Now that we have a directory on the Web server to hold the application code that we want to secure, we need to enable sandbox security. Remember, ColdFusion does not enable sandbox (or resource) security after installation. This allows developers full reign over all resources on the server. Follow these steps to enable sandbox security: 1. Open ColdFusion Administrator. :8LK@FE
Kf \eXYc\ JXe[Yfo j\Zli`kp `e k_\ Dlck`j\im\i Xe[ A)C;QX[XaVhhZhQ"
Read, Write, Execute, and Delete
N
If you are integrating DotNet with a sandbox, make sure that the DotNet classes are saved and enable Read and Execute permissions for X[TgddiQlllgddiQL:7">C;QX[XaVhhZhQ YdicZiegdmn.
N
If you are using OpenOffice in a sandbox, enable the file path permissions listed in Table 55.4.
KXYc\ ,,%+
N
OpenOffice File Path Permissions
FILE PATH
PERMISSIONS
X[TgddiQgjci^bZQhZgkZghQa^W
Read
X[TgddiQgjci^bZQhZgkZghQa^WQ"
Read
X[TgddiQgjci^bZQa^W
Read
X[TgddiQgjci^bZQa^WQ"
Read
egd\gVbTÄaZhQDeZcD[ÄXZ#dg\ (Q
Read and Execute
egd\gVbTÄaZhQDeZcD[ÄXZ#dg\ (Q"
Read and Execute
If you are using disk-based caching in a sandbox, enable Read permission on X[TgddiQ and Read and Write permissions on the disk cache directory. This can be the default cache directory (_VkV#^d#ibeY^g) or a user-specified directory configured in the Y^h`HidgZ property in X[TgddiQa^WQZ]XVX]Z#mba.
a^WQZ]XVX]Z#mba
N
At the time of this writing, 1X[Yjbe3 and lg^iZ9jbe throw an error if the 8gZViZDW_ZXi?VkV function is disabled in the sandbox.
K_\ 9cXZbYfo JXe[Yfo :
Can be used to write cookies to client browsers
8;97>C;D
Can be used to gather information about data source and database objects
214
206
CHAPTER 56
KXYc\ ,-%(
Security in Shared and Hosted Environments
(continued)
TAG
POTENTIAL RISK
8;9>G:8IDGN
Can be used to delete, move, and otherwise affect files and directories
8;9D8JB:CI
Can be used to create FlashPaper and PDF objects
8;:M8=6CCH:GI
Can be used to insert data into data sources
8;>CKD@:
Can be used to instantiate components and Web services and call their methods
8;A96E
Can be used to access LDAP servers
8;AD
A
Can be used to email files on the system
8;D7?:8I
Can be used to create and access COM, component, Java, CORBA, and Web service objects
8;D7?:8I868=:
Can be used to clear all cached queries on the server
8;FJ:GN
Can be used to execute malicious SQL against databases
8;E9;
Can be used to manipulate PDF documents
8;EDE
Can be used to read email files
8;EG>CI
Can be used to send PDF pages in automated batch jobs to a printer
8;G:HIGN
Can be used to read and set Registry keys
8;G:EDGI
Can be used to execute ColdFusion and Crystal Reports report documents
8;H8=:9JA:
Can be used to manipulate the ColdFusion scheduling engine
8;H:6G8=
Can be used to search collections
CFML-Based Risks
KXYc\ ,-%(
(continued)
TAG
POTENTIAL RISK
8;H=6G:ED>CI
Can be used to invoke SharePoint Web services
8;HIDG:9EGD8
Can be used to execute stored procedures on databases
8;I=G:69
Can be used to create autonomous streams of execution
8;IG6CH68I>DC
Can be used to erroneously commit or roll back database transactions
8;JE96I:
Can be used to update data in a data source
KXYc\ ,-%)
ColdFusion Functions and Their Associated Risks
FUNCTION
POTENTIAL RISK
8VX]ZC; directories. This ensures the security of internal system-level templates—including the ColdFusion Administrator. After installation, administrators of shared-hosted environments should immediately create a GDDI sandbox (Figure 56.1). =`^li\ ,-%( Create sandboxes for the root directories on all drives/partitions.
Securing Multiple Server Configurations
The following configuration will remove all resource privileges on the server: N
Data Sources. Disable access to all data sources.
N
CF Tags. Disable access to all tags.
N
CF Functions. Disable access to all functions.
N
Files/Dirs. Remove all secured file and directory mappings.
N
Servers/Ports. Restrict access to the loopback IP address.
N
Others. Disable access to all Java runtime permissions.
Disabling access to all data sources, tags, and functions on the root or system drive completely protects this drive from ColdFusion. Removing all pathnames from the Secured Files and Directories prohibits ColdFusion templates from accessing all files, directories, and subdirectories (and any files therein) on the server. The combination of removing access to the Internet Protocol tags (such as 1X[]iie3, 1X[[ie3, 1X[bV^a3, etc.) and restricting access to the loopback address prevents templates from accessing third-party servers. Adding restrictions on the Others tab prevents access to Java runtime permissions such as the ability to shut down the JVM. ¨ :_Xgk\i ,, \ogcX`ej _fn kf `dgc\d\ek :fc[=lj`fe jXe[Yfo j\Zli`kp%
J\Zli`e^ Dlck`gc\ J\im\i :feÔ^liXk`fej ColdFusion 9 is a J2EE application. The ColdFusion 9 Enterprise Edition is deployable on multiple J2EE application server instances. Supported J2EE application servers include Macromedia JRun, BEA WebLogic, IBM WebSphere, and JBoss. Running ColdFusion in multiple instances on J2EE application servers provides scaling through application isolation and server clustering/ failover. You can combine multiple server instances with multi-homed Web servers to provide complete application and Web site isolation. ¨ =fi `e]fidXk`fe fe ZfeÔ^li`e^ Xggc`ZXk`fe `jfcXk`fe n`k_ dlck`$_fd\[ N\Y j\im\ij# j\\ È<eXYc`e^ Xggc`ZXk`fe `jfcXk`feÉ `e k_\ :feÔ^li`e^ Xe[ 8[d`e`jk\i`e^ :fc[=lj`fe dXelXc Xk ]iie/$$]Zae#VYdWZ#Xdb$ZcTJH$8daY;jh^dc$.#%$6Yb^c$ LHX([[+Y%ZV,,-*.)+&&,'Z%-&&XW[(+)&%)",[X%#]iba%
The ColdFusion MX 7 Enterprise Edition in Multiserver configuration introduced the ability to configure JRun server instances and automatically deploy an instance of ColdFusion to those JRun instances from within the ColdFusion Administrator. Administrators can combine this feature with the J2EE Archives feature to deploy packaged ColdFusion applications that contain the application server, application files (#X[b, #X[X, #X[g, etc.), and server settings (data sources). ¨ :_Xgk\i ,(# È;\gcfp`e^ 8ggc`ZXk`fej#É gifm`[\j dfi\ [\kX`cj fe gXZbX^`e^ :fc[=lj`fe Xggc`ZXk`fe j\im\ij Xj A) Run and type in the path to the executable: X[TgddiQ gjci^bZQW^cQlhXdcÄ\#ZmZ. On Unix/Linux, change directories at the command line to X[TgddiQgjci^bZQ_gZQW^c, and enter .$_VkV "_Vg ##$##$a^W$lhXdcÄ\#_Vg. =`^li\ ,-%, The JRun 4 Web Server Configuration tool.
K@G
Efk`Z\ k_Xk k_\ ZfeÔ^liXk`fe [`i\Zkfip f] k_\ fe\ `ejkXeZ\ ZfeÔ^li\[ Yp k_\ `ejkXcc\i `j Xci\X[p gi\j\ek `e k_\ lhXdcÄ\ kffc n`e[fn%
2. Click Add. The Add Web Server Configuration dialog box opens (Figure 56.6).
219
220
CHAPTER 56
Security in Shared and Hosted Environments
=`^li\ ,-%Point to your Sun ONE server’s configuration directory.
3. Choose Sun ONE Web Server (iPlanet) in the drop-down list for Web Server. Then enter or browse to the configuration directory path of one of your installed servers. 4. Check the box next to Configure Web Server for ColdFusion 9 Applications. 5. Click OK, and click Yes at the response (Figure 56.7). =`^li\ ,-%. Restart the iPlanet Web server instance.
6. The JRun 4 Web Server Configuration window returns (Figure 56.8). The Configured Web Servers list now displays the configuration directory path of your newly configured Sun ONE server instance. =`^li\ ,-%/ Congratulations! You have configured your Web server instance.
7. Click Add to repeat the process for your remaining Web server instances.
Other Issues
EFK
C; (Server configuration) and X[T lZWTgddiQhZgkZghQ hZgkZgTcVbZQH:GK:G">C; (Multiserver configuration). 3. Open the original file in a text editor, and delete or comment out the servlet-mapping entry for #_he as follows: 1"" 1hZgkaZi"bVee^c\3 1hZgkaZi"cVbZ3?HEHZgkaZi1$hZgkaZi"cVbZ3 1jga"eViiZgc3#_he1$jga"eViiZgc3 1$hZgkaZi"bVee^c\3 ""3
4. Save and close the file. 5. Start ColdFusion.
J\Zli`e^ k_\ 8;>9: ;`i\Zkfip The 8;>9: directory path is known as the ColdFusion administration directory. The default path to 8;>9: is lZWgddi$8;>9: for external Web server integration and X[Tgddi$lllgddi$8;>9: when using the internal Web server. The subdirectories in the 8;>9: contain key ColdFusion functionality, which may break if removed from the 8;>9: directory. The following describes some of the subdirectories and the functionality each houses: N
VYb^cVe^. The VYb^cVe^ directory houses the ColdFusion Administrator API code used for programmatic access to ColdFusion Administrator functionality. The ColdFusion Administrator itself implements some of the Admin API components. This directory cannot be moved because the components require the $8;>9:$VYb^cVe^ directory path and the $8;>9: ColdFusion mapping in the administrator. The $8;>9: ColdFusion mapping is not configurable. The Administrator API is discussed in Chapter 57.
N
VYb^c^higVidg. The VYb^c^higVidg directory houses the ColdFusion administrator browser application. This directory cannot be moved because it depends on the $8;>9: mapping and the Admin API code.
N
XaVhhZh.
The XaVhhZh directory houses the Java code (applet and JRE plug-in) used for and X[igZZ Java controls. This directory cannot be moved.
X[\g^Y, X[ha^YZg,
225
226
CHAPTER 56
Security in Shared and Hosted Environments
N
XdbedcZciji^ah.
The XdbedcZciji^ah directory houses the ColdFusion Component Explorer (X[XZmeadgZg), which allows inspection of ColdFusion components. This directory cannot be moved.
N
hXg^eih. The hXg^eih directory houses the JavaScript, Flash components, and style sheets used for 1X[[dgb3 and Ajax support. This code is used to perform client-side validation, create Flash Forms, generate Ajax controls, and apply XML skins. This directory can be moved anywhere on the server and can be pointed to in the ColdFusion Administrator or the hXg^eihgX attributes of 1X[[dgb3 and 1X[V_Vm^bedgi3.
N
l^oVgYh. The l^oVgYh directory houses components used by the ColdFusion Login Wizard extension for Dreamweaver. This directory cannot be moved.
The following are best practices for securing the 8;>9: directory without limiting the functionality of its subdirectories: N
Keep the directory structure intact. Do not remove any of the subdirectories from 8;>9:.
N
Either configure ColdFusion to use the internal Web server during installation—install within the ColdFusion root directory (for example, X[TgddiQlllgddiQ8;>9:)—or move the entire 8;>9: directory structure to a separate document root for your external Web server 8;>9:
N
Create a virtual Web server or virtual directory to access 8;>9:.
K@G
@] pfl dfm\ k_\ 8;>9: [`i\Zkfip# df[`]p k_\ $8;>9: \ekip `e k_\ X[Tgddi$a^W$cZd"gjci^bZ#mba Ôc\ Xe[ i\jkXik :fc[$ =lj`fe% Gf`ek `k kf k_\ XYjfclk\ gXk_ n_\i\ pfl Xi\ dfm`e^ 8;>9:% :fc[=lj`fe dljk Y\ XYc\ kf i\XZ_ k_`j gXk_% N
Apply OS and Web server permissions.
N
Protect access to the ColdFusion Administrator.
N
Leverage the Admin API to provide limited ColdFusion Administrator functionality to users.
N
Only allow access to the ColdFusion Administrator via the internal Web server or a secure Web server instance. Using the internal Web server requires enabling it manually and restarting ColdFusion. Since using the internal Web server is not recommended in production, create a secure Web server instance. Secure the instance with a protected IP address, and only turn the instance on for administrative purposes.
N
When creating sandboxes for applications, only provide read and execute access to the classes and scripts subdirectories.
K@G
@] XZZ\jj kf k_\ :fc[=lj`fe 8[d`e`jkiXkfi `j e\\[\[ ]ifd dlck`gc\ m`iklXc j`k\j# [f efk Zfgp k_\ 8;>9: [`i\Zkfip kf \XZ_ N\Y j\im\i `ejkXeZ\% @ejk\X[# ZfeÔ^li\ m`iklXc [`i\Zkfip dXgg`e^j kf k_\ 8;>9: [`i\Zkfip ]fi k_fj\ j\im\i `ejkXeZ\j%
Other Issues
C`d`k`e^ J\jj`fe K`d\flk MXcl\j Session-scope variables are held in ColdFusion memory space until the session timeout value is reached (or they are cleared with either higjXi8aZVg or higjXi9ZaZiZ). The timeout is the period of inactivity between browser clicks. The Maximum Session Timeout value on the ColdFusion Administrator Memory Variables page defaults to two days. This is too long to let session variables remain in memory. Developers can enable application-specific session timeouts with the HZhh^dcI^bZdji 6eea^XVi^dc#X[X variable and 1X[Veea^XVi^dc3 attribute; however, the Administrator setting is the absolute maximum for the server. In other words, any coded HZhh^dcI^bZdji value greater than the Administrator setting is ignored. Limit the maximum session timeout to 30 to 60 minutes. Remember that the timer restarts with every page request. It is a security hazard to let stale sessions linger on your server—this gives hackers time to impersonate authenticated users. The Maximum Session Timeout is an administrator’s only control over developers’ H:HH>DC scope variables. Sessions can become invalid when J2EE Session Management is enabled and the Session Timeout value (in the Administrator or in developer’s code) is greater than the J2EE Session Timeout value. Synchronize the ColdFusion Administrator’s Maximum Session Timeout and J2EE Session Timeout values. The J2EE Session Timeout value is configurable in the hZhh^dc"i^bZdji value in the lZW#mba descriptor file found in X[Tgddi$L:7">C;$ (Server configuration) or X[TlZWTgddi$L:7">C; (Multiserver/J2EE configuration). Read Adobe Tech Note 19190 at ]iie/$$lll#VYdWZ#Xdb$\d$icT&.&%. for more information. :8LK@FE
K_\ j\jj`fe j\kk`e^j X]]\Zk k_\ \ek`i\ j\im\i% @] A)9 Xe[ 8;ID@:C% :fc[=lj`fe n`cc jk`cc j\e[ k_\ 8;>9 Xe[ 8;ID@:C Zffb`\ mXcl\j# Ylk H:HH>DC# HZhh^dc>9 Y\Zfd\j k_\ _hZhh^dc^Y mXcl\% K_`j dXp Yi\Xb jfd\ Xggc`ZXk`fej k_Xk i\cp fe 8;>9 Xe[ 8;ID@:C Xj k_\ j\jj`fe `[\ek`Ô\i% =fi dfi\ [\kX`cj Zfejlck k_\ :fc[=lj`fe [fZld\ekXk`fe fi K\Z_ Efk\ (/)*)# ?fn kf <eXYc\ A)67A:H#XjggZci9HC!ºiZmicdXVhZºº ^cYZm2ºYº3 1ig31iY3Y1$iY31iY3K6G>67A:H#XjggZci9HCPYR#Yg^kZg1$iY31iY3K6G>67A:H#XjggZci9HCPYR# XaVhh1$iY31$ig3 1$XÅdde31$X[djieji3 1$iVWaZ31$e3
C`jk`e^ ,.%*
^e;dgb#X[b —Adding
an IP for Debugging
1X[hZii^c\ ZcVWaZX[djiejidcan2ºnZhº3 1""" ;^aZ cVbZ/ ^e;dgb#X[b 9ZhXg^ei^dc/ ;dgb [dg VYY^c\ >E VYYgZhhZh id i]Z 9ZWj\\^c\ >E GZhig^Xi^dc A^hi 6hhjbei^dch/ 6XXZhh id i]Z 6Yb^c 6E> XdYZ WVhZ $8;>9:$VYb^cVe^ k^V [VXVYZ#X[X 6ji]dg cVbZ VcY Z"bV^a/ HVg\Z hhVg\Zci5 hVg\ZlVn#Xdb 9ViZ 8gZViZY/ ;ZWgjVgn '-! '%%* """3 1X[ign31""" >[ Vc >E ^h hjWb^iiZY i]Zc eVhh ^i id i]Z hZi>E bZi]dY! di]Zgl^hZ hZi>E jhZh i]Z XjggZci >E# """3 1XÄ[ ^h9ZÄcZY»;DGB#hjWb^i¼3 1X[hZi G:FJ:HI#bn6Yb^cDW_#hZi>E;DGB#^e3 1X[ZahZ^[ ^h9ZÄcZY»;DGB#XjggZci>E¼3 1X[hZi G:FJ:HI#bn6Yb^cDW_#hZi>E3 1$XÄ[3 1X[XViX] ineZ2ºVcnº31""" 9^heaVn Vcn Zggdg bZhhV\Zh# """3 1X[djieji31]( hinaZ2ºXdadg/ gZYº38;86I8=#bZhhV\Z1$](31$X[djieji3 1$X[XViX]3 1$X[ign3 1X[hZii^c\ ZcVWaZX[djiejidcan2ºcdº3 1e36YY Vc >E VYYgZhh dg hjWb^i i]Z XjggZci >E VYYgZhh1$e3 1X[[dgb cVbZ2º^e;dgbº3 1iVWaZ WdgYZg2º%º3 1ig31iY3>E 6YYgZhh1$iY31iY31XÄceji ineZ2ºiZmiº cVbZ2º^eº31$iY31$ig3 1ig31iY31XÄceji ineZ2ºhjWb^iº cVbZ2ºhjWb^iº kVajZ2ºHjWb^iº31$iY31iY31XÄceji ineZ2ºhjWb^iº cVbZ2ºXjggZci^eº kVajZ2º6YY 8jggZciº31$iY31$ig3 1$iVWaZ3 1$X[[dgb3 1]g31""" 9^heaVn V a^hi d[ XjggZci >Eh """3 1iVWaZ WdgYZg2º%º l^Yi]2º'*%º3 1ig31i]38jggZci >E 6YYgZhhZh1$i]31$ig3 1X[djieji31XÅdde a^hi2ºG:FJ:HI#bn6Yb^cDW_#\Zi>EA^hiº ^cYZm2º^º3 1ig31iY3^1$iY31$ig3 1$XÅdde31$X[djieji3 1$iVWaZ3
241
242
CHAPTER
57
Using the Administrator API
J\Zli`kp @dgc`ZXk`fej ]fi k_\ 8[d`e 8G@ Before using the ColdFusion Admin API, certain security implications need consideration. Administrators must understand the potential for allowing unfettered access to the ColdFusion Administrator. ColdFusion secures the ColdFusion Administrator with a single password, which administrators should not provide to users. Administrators must also enable access to the Admin API code directory: $8;>9:$6Yb^c6E>. This directory is installed by default, and the API modules are hardcoded to look for this path.
:fc[=lj`fe HZgk^XZ;VXidgn Soon after ColdFusion MX was released, developers learned how to access the ColdFusion HZgk^XZ;VXidgn object, by using 8gZViZDW_ZXi and 1X[dW_ZXi3 calls to XdaY[jh^dc#hZgkZg# HZgk^XZ;VXidgn. This Java object gave developers complete access to all ColdFusion server objects, including the Data Source, Licensing, Runtime, and Security Services. It also allowed developers to bypass the ColdFusion Administrator to programmatically configure data sources, debugging, and so on. Hackers could also use it to disable the admin and RDS passwords and gain complete control over the server. In response, Macromedia expanded the sandbox security restrictions in ColdFusion MX 7 for 8gZViZDW_ZXi, allowing administrators to disable access to Java objects. This allowed administrators to use sandbox security to disable HZgk^XZ;VXidgn access. Adobe improved HZgk^XZ;VXidgn security in ColdFusion 8 by providing the Disable Access to Internal ColdFusion Java Components ColdFusion Administrator option. This option prevents unauthorized access to the internal ColdFusion objects while permitting developer access to other legitimate Java objects. Using this option with sandbox security and user-based administrator access, administrators have control over Admin API access. EFK
# """3 1XÄ[ >h9ZÄcZY»H:HH>DC#bn6Yb^cDW_¼3 1X[hZi H:HH>DC#bn6Yb^cDW_#ad\dji3 1""" 8aZVg i]Z [VXVYZ dW_ZXi [gdb i]Z H:HH>DC hXdeZ# """3 1X[hZi HigjXi9ZaZiZH:HH>DC! bn6Yb^cDW_3 1$XÄ[3 1$XÅdX`3 1""" Ad\ i]Z jhZg dji d[ 8daY;jh^dc# """3 1XÅd\dji3 1$XÄ[3 1""" 8;ADC higjXijgZ [dg Vji]Zci^XVi^dc XdYZ# """3 1XÅd\^c3 1X[hZi G:FJ:HI#ad\\ZY^c 2 [VahZ3 1XÄ[ >h9ZÄcZY¹XÅd\^cº3 1""" 6ji]Zci^XViZ VcY ad\^c jhZg id 8daY;jh^dc l^i] Veegdeg^ViZ gdaZh# """3 1XÄ[ cdi 8dbeVgZCd8VhZ»VYb^c¼! Ig^b8;ADC#cVbZ VcY cdi 8dbeVgZCd8VhZIg^b8;ADC#eVhhldgY! ¹eVhhldgYº3 1XÅd\^cjhZg cVbZ2º8;ADC#cVbZº eVhhldgY2º8;ADC#eVhhldgYº gdaZh2ºVYb^c!ejWa^h]Zgº3 1X[hZi G:FJ:HI#ad\\ZY^c 2 ¹igjZº3 1X[ZahZ3 1X[hZi G:FJ:HI#WVYad\^c 2 ¹igjZº3 1X[hZi G:FJ:HI#ad\\ZY^c 2 ¹[VahZº3 1""" >[ i]Z ad\^c [V^ah! gZijgc id i]Z ad\^c [dgb# """3 1XÄcXajYZ iZbeaViZ2ºad\^c[dgb#X[bº31X[VWdgi3 1$XÄ[3
245
246
CHAPTER
57
Using the Administrator API
1X[ZahZ3 1XÄcXajYZ iZbeaViZ2ºad\^c[dgb#X[bº31X[VWdgi3 1$XÄ[3 1$XÅd\^c3 1XÄ[ AZcIg^b# """3 1X[hZi H:HH>DC#bn6Yb^cDW_ 2 XgZViZDW_ZXi¹XdbedcZciº! ¹dlh#X]VeiZg*,# [VXVYZº#ad\^c67A:H#VYb^cEVhhlY;^aZ! ¹6Yb^cTEVhhº! ¹eVhhldgYº3 1$XÄ[3 1""" 8gZViZ V G:FJ:HI hXdeZ ed^ciZg [dg jhZ ^c di]Zg iZbeaViZh dc hjWhZfjZci gZfjZhih# """3 1X[hZi G:FJ:HI#bn6Yb^cDW_ 2 H:HH>DC#bn6Yb^cDW_3 1$XÅdX`3 1X[djieji3 1""" 6YY Ad\dji 7jiidc Vide ZkZgn eV\Z# """3 1X[[dgb cVbZ2º:m^iº VXi^dc2º^cYZm#X[bº3 1XÄceji ineZ2ºhjWb^iº cVbZ2ºAd\djiº kVajZ2ºAd\djiº3 1$X[[dgb3 1$X[djieji3 1$XÄ[3 1$X[[jcXi^dc3 1X[[jcXi^dc cVbZ2ºdcHZhh^dc:cYº gZijgcineZ2ºkd^Yº3 1X[Vg\jbZci cVbZ2ºHZhh^dcHXdeZº gZfj^gZY2ºigjZº3 1X[Vg\jbZci cVbZ2º6eea^XVi^dcHXdeZº gZfj^gZY2º[VahZº3 1XÅdX` hXdeZ2ºhZhh^dcº i^bZdji2º(%º i]gdldci^bZdji2ºnZhº3 1XÄ[ >h9ZÄcZY¹H:HH>DC#bn6Yb^cDW_º3 1""" :chjgZ i]Z jhZg ^h ad\\ZY dji d[ i]Z 6Yb^c 6E># """3 1X[hZi H:HH>DC#bn6Yb^cDW_#ad\dji3 1""" :chjgZ i]Z [VXVYZ dW_ZXi ^h XaZVgZY [gdb i]Z H:HH>DC hXdeZ# """3 1X[hZi HigjXi9ZaZiZH:HH>DC! bn6Yb^cDW_3 1$XÄ[3 1$XÅdX`3 1""" :chjgZ i]Z jhZg ^h ad\\ZY dji d[ 8daY;jh^dc# """3 1XÅd\dji3 1$X[[jcXi^dc3 1$X[XdbedcZci3
Listing 57.4 shows the CF Admin password hard-coded in the 6eea^XVi^dc#X[X (see the K6G>67A:H#VYb^cEVhhlY variable). This is necessary for the façade to work. The code uses K6G>67A:H# VYb^cEVhhlY to authenticate to the [VXVYZ#X[X. Revisit the [VXVYZ#X[X code in Listing 57.1. We can secure the method calls using the 1X[[jcXi^dc3 gdaZh attribute. Specifying gdaZh2ºVYb^cº will require users to authenticate with the role of VYb^c in order to run the façade methods. (This sample code provided for this chapter is already secured with gdaZh2ºVYb^cº.)
Admin API Best Practices
K@G
K_\ [VXVYZ#X[X d\k_f[j `e C`jk`e^ ,.%( Xi\ Xcjf XmX`cXYc\ Xj N\Y j\im`Z\j Yp m`ikl\ f] VXXZhh2ºgZbdiZº `e k_\ 1X[[jcXi^dc3 ZXccj% N_\e gdaZh2ºVYb^cº `j jg\Z`Ô\[ i\dfk\ Zc`\ekj Xi\ Xcjf i\hl`i\[ kf Xlk_\ek`ZXk\ kf :fc[=lj`fe Xj X lj\i n`k_ k_\ VYb^c ifc\ `e fi[\i kf lj\ k_\ N\Y j\im`Z\%
The 6eea^XVi^dc#X[X ensures only authorized ColdFusion users can access the [VXVYZ#X[X. It forces users to a login form where they must enter authentication criteria. Upon successful authentication, 1XÅd\^cjhZg3 logs the user into the ColdFusion security paradigm with the role of VYb^c. If DC scope and authenticated to the Admin API: 1XÄ[ CDI >h9ZÄcZY¹H:HH>DC#bn6Yb^cDW_º3 1X[hZi H:HH>DC#bn6Yb^cDW_ 2 XgZViZDW_ZXi¹XdbedcZciº! ¹dlh#X]VeiZg*,#[VXVYZº# ad\^cK6G>67A:H#VYb^cEVhhlY3 1$XÄ[3
This H:HH>DC scope object ensures authenticated access for every request during the user’s session. Next, provide a handle to the H:HH>DC object in the G:FJ:HI scope to eliminate any locking concerns: 1X[hZi G:FJ:HI#bn6Yb^cDW_ 2 H:HH>DC#bn6Yb^cDW_3
Finally, the 6eea^XVi^dc#X[X includes logout code to exit the Admin API, logout of ColdFusion, and destroying of the H:HH>DC scope façade object: 1XÅdX` hXdeZ2ºhZhh^dcº i^bZdji2º(%º i]gdldci^bZdji2ºnZhº3 1XÄ[ >h9ZÄcZY¹H:HH>DC#bn6Yb^cDW_º3 1""" :chjgZ i]Z jhZg ^h ad\\ZY dji d[ i]Z 6Yb^c 6E># """3 1X[hZi H:HH>DC#bn6Yb^cDW_#ad\dji3 1""" :chjgZ i]Z [VXVYZ dW_ZXi ^h XaZVgZY [gdb i]Z H:HH>DC hXdeZ # """3 1X[hZi HigjXi9ZaZiZH:HH>DC! bn6Yb^cDW_3 1$XÄ[3 1$XÅdX`3 1""" :chjgZ i]Z jhZg ^h ad\\ZY dji d[ 8daY;jh^dc# """3 1XÅd\dji3
EFK
9:$VYb^cVe^). N
Create sandboxes for all application directories, and only enable access to the Admin API directory for the custom admin console. Console code needs only read and execute permissions on the Admin API files and folders.
N
Enable operating system permissions. The ColdFusion user (usually LocalSystem on Windows, nobody on Unix) and administrator (or root) accounts should have full control. Only allow read and execute access for the Web server user and other authenticated users.
N
Only allow access to the Admin API through custom console code.
:ljkfd :fejfc\ :f[`e^ 9\jk GiXZk`Z\j Here are a few custom console coding best practices: N
Code custom admin modules that provide end-user access to the Admin API.
N
Create methods with the same name as the API methods to avoid uncertainty.
N
Limit the access to segments of Admin API features: N
No access to anything requiring restart.
N
No access to the hZXjg^in#X[X or gjci^bZ#X[X.
N
Limit access to serverwide settings: DSNs, mappings, debugging settings, and so on.
N
Limit functionality to adding and modifying settings. All delete functionality should be done via the ColdFusion Administrator by administrators.
N
Secure the custom admin modules:
N
N
Leverage the roles’ 1X[[jcXi^dc3 attribute to enforce user security.
N
If you’re hard-coding the ColdFusion Administrator password, pass it as a local variable to the ad\^c method of VYb^c^higVidg#X[X.
Encrypt the custom admin console templates with the X[Xdbe^aZ utility. See the section on sourceless deployment in Chapter 51, “Deploying Applications,” for details on using X[Xdbe^aZ to encrypt ColdFusion templates.
G8IK
((
86I>DC. Even though it can maintain a connection across multiple pages, it is recommended that you keep it open only for the duration of your requests. Managing the number of unique connections to the FTP server is critical because most FTP servers allow a set number of concurrent connections at any one time. Having a persistent connection to the FTP server effectively ties up one of the connections to the server Depending on the FTP server you are connecting to, making changes to cached connection settings, such as changing gZign8djci or i^bZdji, will require shutting down and reestablishing the connection.
=`c\ Xe[ ;`i\Zkfip Fg\iXk`fej n`k_ 1X[[ie3 After you establish an FTP connection, you can perform various file and directory operations to send files to the server or receive files and directory listings from the server. Table 58.5 shows the attributes for file and directory operations. KXYc\ ,/%, 1X[[ie3 File and Directory Operation Attributes ATTRIBUTE
DESCRIPTION
VXi^dc
Required if the connection is not already cached using the XdccZXi^dc attribute. Determines the FTP operation to perform. It can be one of the following: 8]Vc\Z9^g, 8gZViZ9^g, GZbdkZ9^g, A^hi9^g, [:m^hih
Optional. N:H or CD. Defaults to N:H. Specifies whether a h 9^gZXidgn1$i]3 1$ig3 1ig3 1""" Djieji i]Z gZhjaih d[ i]Z Y^gZXidgn a^hi^c\ """3 1X[djieji fjZgn2ºY^ga^hiº3 1iY3Y^ga^hi#cVbZ1$iY3 1iY3Y^ga^hi#eVi]1$iY3 1iY3Y^ga^hi#jga1$iY3 1iY3Y^ga^hi#aZc\i]1$iY3 1iY3YViZ;dgbViY^ga^hi#aVhibdY^ÄZY1$iY3 1iY3Y^ga^hi#^h9^gZXidgn1$iY3 1$ig3 1$X[djieji3 1$iVWaZ3 1""" XadhZ XdccZXi^dc """3 1X[[ie VXi^dc2ºXadhZº XdccZXi^dc2ºbdoº hideDc:ggdg2ºnZhº3
Let’s step through the code example. The first thing that happens is that a named connection to the Mozilla FTP server ([ie#bdo^aaV#dg\) is established under the name ¹Bdoº. This allows all other FTP requests to use this name in their XdccZXi^dc attribute instead of specifying the connection information in each request. Next, the current directory is changed to $ejW$bdo^aaV#dg\. After this, a \Zi8jggZci9^g action is run to confirm that the directory was changed. Then a A^hi" 9^g action is run to get the contents of the directory. The result of the directory listing is stored as a query object in the variable specified in the cVbZ attribute, which in our example is ¹Y^ga^hiº. After grabbing the directory listing, the results are output into an HTML table by using 1X[djieji3. Figure 58.3 shows the output from this example.
Putting to Use
=`^li\ ,/%* The 1X[[ie3 directory listing.
When requesting a directory listing, the results are stored in a query object. The cVbZ attribute of the 1X[[ie3 is set to the name of the query object that is to be created. After it is created, the query object can be manipulated just as if it were created with 1X[fjZgn3. Information about each file or subdirectory found in the specified directory is stored in a separate row in the query. The columns of the created query object are shown in Table 58.10. KXYc\ ,/%(' 1X[[ie3 Query Object Definitions COLUMN
DESCRIPTION
CVbZ
Name of the file or directory.
EVi]
File path (without drive designation).
JGA
Complete URL of the file or directory.
AZc\i]
Number indicating the size of the file.
AVhiBdY^ÄZY
Date/Time value indicating when the file or directory was last modified.
6iig^WjiZh
String indicating attributes of the file or directory.
>h9^gZXidgn
Boolean value indicating whether the element is a directory.
BdYZ
Applies only to Solaris and HP-UX. Permissions. Octal string.
Lj`e^ 1X[[ie3 kf ;fnecfX[ X =`c\ The 1X[[ie3 tag can be used to download a file from an FTP server to your local machine. Listing 58.10 shows the code used to download a file, which in this case is the G:69B: file for the [ie# bdo^aaV#dg\ server. In this example the hideDc:ggdg is set to ;6AH:, so the 8;;IE variables are checked for success. If the file type (binary or ASCII) is known ahead of time, igVch[ZgBdYZ can be specified ahead of time. If it is not known, the default of Vjid should be used.
273
274
CHAPTER
58
Using Server-Side HTTP and FTP
C`jk`e^ ,/%(' [ieT\ZiÄaZ#X[b —Code to Download a File Using 1X[[ie3 1""" ;^aZcVbZ/ [ieT\ZiÄaZ#X[b EjgedhZ/ 9d V h^beaZ ;IE deZgVi^dc VcY \Zi V ÄaZ """3 1X[[ie VXi^dc2ºdeZcº jhZgcVbZ2ºVcdcnbdjhº eVhhldgY2ºº hZgkZg2º[ie#bdo^aaV#dg\º XdccZXi^dc2ºbdoº hideDc:ggdg2ºnZhº3 1X[[ie XdccZXi^dc2ºbdoº VXi^dc2ºX]Vc\Z9^gº Y^gZXidgn2º$ejW$bdo^aaV#dg\º3 1X[[ie XdccZXi^dc2ºbdoº VXi^dc2ºC6GNº [V^a>[:m^hih2ºCdº3 1X[djieji3 ;IE DeZgVi^dc ;IE DeZgVi^dc ;IE DeZgVi^dc ;IE DeZgVi^dc 1$X[djieji3
GZijgc KVajZ/ X[[ie#gZijgcKVajZ1Wg3 HjXXZhh[ja/ X[[ie#hjXXZZYZY1Wg3 :ggdg 8dYZ/ X[[ie#Zggdg8dYZ1Wg3 :ggdg BZhhV\Z/ X[[ie#ZggdgIZmi1Wg3
Lj`e^ 1X[[ie3 kf LgcfX[ X =`c\ The 1X[[ie3 tag can also be used to push a file to an FTP server from your local machine. Listing 58.11 shows the code used to push a file. Again, if the file type (binary or ASCII) is known ahead of time, the igVch[ZgBdYZ can be specified ahead of time. If it is not known, the default Vjid9ZiZXi should be used. This listing uses an FTP server local to the machine itself. You will need to modify the settings for the listing to work. C`jk`e^ ,/%(( [ieTejiÄaZ#X[b —Using 1X[[ie3 to Upload a File 1X[hZi [ieHZgkZg 2 ¹&',#%#%#&º3 1X[hZi jhZgcVbZ2º[ddº3 1X[hZi eVhhldgY2ºbddº3 1X[[ie VXi^dc2ºdeZcº jhZgcVbZ2ºjhZgcVbZº eVhhldgY2ºeVhhldgYº hZgkZg2º[ieHZgkZgº XdccZXi^dc2ºbnXdcº hideDc:ggdg2ºnZhº3 1""" I]Z ÄaZ id eji je# """3 1X[hZi adXVa;^aZ 2 \Zi9^gZXidgn;gdbEVi]\Zi8jggZciIZbeaViZEVi] \Zi;^aZ;gdbEVi]\Zi8jggZciIZbeaViZEVi]3 1X[djieji31e3Bdk^c\ je adXVa;^aZ1$e31$X[djieji3 1X[[ie VXi^dc2ºejiÄaZº hideDc:ggdg2ºnZhº XdccZXi^dc2ºbnXdcº adXVa;^aZ2ºadXVa;^aZº gZbdiZ;^aZ2º\Zi;^aZ;gdbEVi]\Zi8jggZciIZbeaViZEVi]º igVch[ZgbdYZ2ºVjid9ZiZXiº3 1X[djieji3 ;IE DeZgVi^dc GZijgc KVajZ/ X[[ie#gZijgcKVajZ1Wg3 ;IE DeZgVi^dc HjXXZhh[ja/ X[[ie#hjXXZZYZY1Wg3 ;IE DeZgVi^dc :ggdg 8dYZ/ X[[ie#Zggdg8dYZ1Wg3
Putting to Use
C`jk`e^ ,/%((
(continued)
;IE DeZgVi^dc :ggdg BZhhV\Z/ X[[ie#ZggdgIZmi1Wg3 1$X[djieji3 1X[[ie VXi^dc2ºXadhZº XdccZXi^dc2ºbnXdcº hideDc:ggdg2ºnZhº3
The template begins by specifying the settings for the FTP server, username, and password. As mentioned earlier, you will need to modify these values in order for this script to work. A connection is opened using these settings. Next, we create a variable, adXVa;^aZ, that points to this template itself. This file is uploaded to the remote server using the same name as the local file (although without the directory). After the file is uploaded, the values in the 8;;IE struct are displayed. Lastly, the connection is closed. When you interact with a server and manipulate files or directories, security becomes an issue. You can do a couple of things to minimize your exposure during FTP communication. First, if you are not looking to have public anonymous access, move the FTP from port 21 (the default) to a different port. This is then broadcast only to your partners who need to use the site. Second, restrict certain functionality and directories to certain user accounts, so that you only expose what is absolutely necessary for each user. The 1X[[ie3 tag has the jhZgcVbZ, eVhhldgY, and edgi attributes, which can all be used to deal with this issue.
J\Zli\ =KG :fee\Zk`fej ColdFusion also supports secure FTP connections via Secure Shell File Transfer Protocol (SFTP). To enable a connection to a secure FTP server, simply add the hZXjgZ2ºN:Hº attribute to a 1X[iie3 tag. Optional attributes added to the tag include Äc\Zgeg^ci, `Zn, and eVhhe]gVhZ (covered in Table 58.4). Outside the connection attributes, your interactions with the FTP server will remain the same. FTP over SSL (FTPs) currently is not supported.
Lj`e^ =KG n`k_ JZi`gk`e^ In addition to HTTP support in CFScript, ColdFusion 9 adds the capability to perform FTP operations in script. As with HTTP, there is no benefit or drawback to using FTP in CFScript; just use the syntax that you prefer. Again, as with HTTP, we will use a component to perform FTP operations: [ieHZgk^XZ 2 cZl [ie
Let’s look at an example. Listing 58.12 is a modified version of Listing 58.9. C`jk`e^ ,/%() [ieThXg^ei#X[b —FTP Operations in CFScript 1X[hXg^ei3 [ieHZgk^XZ 2 cZl [ie0 $$hZi Viig^WjiZh [ieHZgk^XZ#hZiJhZgcVbZ¹Vcdcnbdjhº0 [ieHZgk^XZ#hZiEVhhldgY¹º0 [ieHZgk^XZ#hZiHZgkZg¹[ie#bdo^aaV#dg\º0 [ieHZgk^XZ#hZiHideDc:ggdgigjZ0
275
276
CHAPTER
58
C`jk`e^ ,/%()
Using Server-Side HTTP and FTP
(continued)
[ieHZgk^XZ#hZi8dccZXi^dc¹bdoº0 $$deZc ^i [ieHZgk^XZ#deZc0 $$X]Vc\Z Y^gZXidgn [ieHZgk^XZ#X]Vc\Z9^gY^gZXidgn2º$ejW$bdo^aaV#dg\º0 $$\Zi XjggZci Y^gZXidgn gZhjai 2 [ieHZgk^XZ#\Zi8jggZci9^g0 XjggZci9^g 2 gZhjai#\ZiEgZÄm#gZijgcKVajZ0 lg^iZDjieji¹8jggZci Y^gZXidgn dc ;IE XdccZXi^dc/ XjggZci9^g 1e$3º0 $$\Zi i]Z ÄaZh gZhjai 2 [ieHZgk^XZ#a^hi9^gY^gZXidgn2XjggZci9^g!cVbZ2ºÄaZhº0 lg^iZ9jbegZhjai#\ZiGZhjai0 $$XadhZ i]Z XdccZXi^dc [ieHZgk^XZ#XadhZXdccZXi^dc2ºbdoº0 1$X[hXg^ei3
All in all, Listing 58.12 should be pretty understandable since we aren’t doing anything new—just using CFScript syntax instead. The listing creates an instance of the FTP component available to all CFML pages. After it has this component, it can set various options for our connection. After everything is set up, the connection can be opened, traversed, and listed. Again, this approach is no better (or worse) than the tag version. It’s simply an alternative.
JlddXi`q`e^ k_\ 1X[[ie3 KX^ The preceding examples demonstrate how to use the 1X[[ie3 tag to transfer and view files across networks. Though using FTP is simple, the options it provides as it becomes a reaction to a needed business process make it a significant addition to ColdFusion.
:?8GKc [VXi! V edgiIneZ ^h Vabdhi ZmVXian a^`Z V 8;8 ^c i]Vi ^i XdciV^ch bZi]dYh Wji XVc¼i WZ ^chiVci^ViZY VcY YdZhc¼i ]VkZ bZbWZg kVg^VWaZh# 6c deZgVi^dc ^h ZmigZbZan h^b^aVg id V [jcXi^dc ^c V higjXijgZY egd\gVbb^c\ aVc\jV\Z hjX] Vh 8 dg 8daY;jh^dc# ""3 1$lhYa/edgiIneZ3 1lhYa/W^cY^c\3 1"" 8dYZ l^i]^c i]Z deZc^c\ VcY Xadh^c\ 1lhYa/W^cY^c\3 iV\ YZÄcZh i]Z LH9A ¹W^cY^c\º d[ YViV ineZh [dg Vaa ^ceji VcY djieji eVgVbZiZgh Vh lZaa Vh id i]Z^g ZcXdY^c\ hinaZ# ""3 1$lhYa/W^cY^c\3 1lhYa/hZgk^XZ3 1"" L^i]^c V 1lhYa/hZgk^XZ3 iV\ ^h V 1lhYa/edgi3 edgi! l]^X] YZÄcZh i]Z XdccZXi^dc ed^ci id V LZW HZgk^XZ VcY ^ih HD6E W^cY^c\# ""3 1$lhYa/hZgk^XZ3 1$lhYa/YZÄc^i^dch3
281
282
CHAPTER
59
Creating and Consuming Web Services
Now that we have looked at the layout of WSDL and definitions of the tag elements that make up a document, we need to examine a simple WSDL document and get familiar with its syntax. To give us something for comparison with our WSDL document, here is an extremely simple ColdFusion Component (CFC) that is being deployed as a Web service. Listing 59.2 shows the Number-to-String Conversion Web service. C`jk`e^ ,0%)
CjbZg^XHig^c\#X[X —Number-to-String
Conversion Web Service
1""" 6JI=DG/ 7gZcYVc D¼=VgV Wd]VgV5ZiZX]hdaji^dch#Xdb L:7 H:GK>8:/ CjbZg^XHig^c\#X[X 9:H8G>EI>DC/ 8daY;jh^dc 8;8 YZeadnZY Vh V LZW HZgk^XZ id gZijgc V eVhhZY"^c ^ciZ\Zg ^cid ^ih Hig^c\ gZegZhZciVi^dc# 6G<JB:CIH/ cVbZ2ºcjbWZgCjbZg^Xº ineZ2ºcjbZg^Xº gZfj^gZY2º[VahZº YZ[Vjai2º%º """3 1""" =ZgZ ^h V Y^heaVn cVbZ [dg i]Z 8;8$LH l^i] V ]^ci# """3 1X[XdbedcZci Y^heaVncVbZ2ºCjbZg^XHig^c\º djieji2º[VahZº ]^ci2º8dckZgih V cjbWZg id ^ih Hig^c\ gZegZhZciVi^dcº3 1""" =ZgZ ^h i]Z dcan [jcXi^dc ^c i]Z 8;8# LZ `cdl ^i ^h YZeadnZY Vh V LZW HZgk^XZ WZXVjhZ ^ih VXXZhh kVg^VWaZ ^h hZi id ¹gZbdiZº """3 1X[[jcXi^dc cVbZ2º>ciZ\ZgIdHig^c\º gZijgcIneZ2ºhig^c\º djieji2º[VahZº VXXZhh2ºgZbdiZº3 1""" =ZgZ ^h i]Z Vg\jbZci kVg^VWaZ """3 1X[Vg\jbZci cVbZ2ºcjbWZgCjbZg^Xº ineZ2ºcjbZg^Xº gZfj^gZY2ºigjZº3 1X[hZi kVg gZijgcHig^c\ 2 ¹º3 1""" =ZgZ ^h i]Z ¹ad\^Xº d[ i]Z 8;8 LZW HZgk^XZ """3 1X[hl^iX] ZmegZhh^dc2ºVg\jbZcih#cjbWZgCjbZg^Xº3 1X[XVhZ kVajZ2º%º31X[hZi gZijgcHig^c\ 2 ¹OZgdº31$X[XVhZ3 1X[XVhZ kVajZ2º&º31X[hZi gZijgcHig^c\ 2 ¹DcZº31$X[XVhZ3 1X[XVhZ kVajZ2º'º31X[hZi gZijgcHig^c\ 2 ¹Ildº31$X[XVhZ3 1X[XVhZ kVajZ2º(º31X[hZi gZijgcHig^c\ 2 ¹I]gZZº31$X[XVhZ3 1X[XVhZ kVajZ2º)º31X[hZi gZijgcHig^c\ 2 ¹;djgº31$X[XVhZ3 1X[XVhZ kVajZ2º*º31X[hZi gZijgcHig^c\ 2 ¹;^kZº31$X[XVhZ3 1X[XVhZ kVajZ2º+º31X[hZi gZijgcHig^c\ 2 ¹H^mº31$X[XVhZ3 1X[XVhZ kVajZ2º,º31X[hZi gZijgcHig^c\ 2 ¹HZkZcº31$X[XVhZ3 1X[XVhZ kVajZ2º-º31X[hZi gZijgcHig^c\ 2 ¹:^\]iº31$X[XVhZ3 1X[XVhZ kVajZ2º.º31X[hZi gZijgcHig^c\ 2 ¹C^cZº31$X[XVhZ3 1X[YZ[VjaiXVhZ3 1X[hZi gZijgcHig^c\ 2 ¹L]Vi Vb > V bVi]ZbVi^X^Vc4º3 1$X[YZ[VjaiXVhZ3 1$X[hl^iX]3 1""" Cdl lZ gZijgc i]Z gZijgcHig^c\ kVg^VWaZ """3 1X[gZijgc gZijgcHig^c\3 1$X[[jcXi^dc3 1$X[XdbedcZci3
This is a ColdFusion Component that is being deployed as a Web service. We know this because the VXXZhh variable of at least one function is set to GZbdiZ. When we examine this CFC, we notice it contains a single function: The >ciZ\ZgIdHig^c\ function takes one argument named cjbWZgCjbZg^X, which is of cjbZg^X type and is required.
WSDL
When >ciZ\ZgIdHig^c\ is called, the passed value cjbWZgCjbZg^X is evaluated in a 1X[hl^iX]3 tag’s ZmegZhh^dc statement. The corresponding 1X[XVhZ3 tag sets the variable gZijgcHig^c\ with the appropriate string representation of the cjbZg^XCjbWZg variable. Finally, the gZijgcHig^c\ is returned to the Web service caller by the 1X[gZijgc3 tag. To display the WSDL for this CFC Web service, we append the string 4lhYa to the CFC’s URL. EFK
ciZ\ZgIdHig^c\º eVgVbZiZgDgYZg2ºcjbWZgCjbZg^Xº3 1lhYa/^ceji bZhhV\Z2º^bea/>ciZ\ZgIdHig^c\GZfjZhiº cVbZ2º>ciZ\ZgIdHig^c\GZfjZhiº$3 1lhYa/djieji bZhhV\Z2º^bea/>ciZ\ZgIdHig^c\GZhedchZº cVbZ2º>ciZ\ZgIdHig^c\GZhedch Zº$3 1lhYa/[Vjai bZhhV\Z2º^bea/8;8>ckdXVi^dc:mXZei^dcº cVbZ2º8;8>ckdXVi^dc:mXZei^dcº$3 1$lhYa/deZgVi^dc3 1$lhYa/edgiIneZ3
On the first line of our WSDL code block, we notice that the edgiIneZ matches the name of the #X[X file and really represents the .X[X and the Web service. In Java or object-oriented terms, you can think of the edgiIneZ as being similar to a Java class. A edgi or edgiIneZ defines the operations provided by a Web service and their associated inputs and outputs. An deZgVi^dc in WSDL, and therefore in Web services, is very similar in function to a method name in Java or a function name in C++. The deZgVi^dc in the second line of our sample code defines the >ciZ\ZgIdHig^c\ operation. Directly below the operation definition are our lhYa/^ceji, lhYa/djieji, and lhYa/[Vjai tags. lhYa/^ceji and lhYa/djieji contain a predefined message and aren’t that helpful in determining what our Web service is doing or what we would need to do to call it. The lhYa/[Vjai tag catches errors and outputs the applicable error message. The bZhhV\Z and eVgi tags really define the input parameters and the return value of our function. Listing 59.4 shows that WSDL snippet. C`jk`e^ ,0%+
CjbZg^XHig^c\#X[X —The bZhhV\Z
and eVgi Tags from Our WSDL
1lhYa/bZhhV\Z cVbZ2º>ciZ\ZgIdHig^c\GZfjZhiº3 1lhYa/eVgi cVbZ2ºcjbWZgCjbZg^Xº ineZ2ºmhY/YdjWaZº$3 1$lhYa/bZhhV\Z3 1lhYa/bZhhV\Z cVbZ2º>ciZ\ZgIdHig^c\GZhedchZº3 1lhYa/eVgi cVbZ2º>ciZ\ZgIdHig^c\GZijgcº ineZ2ºmhY/hig^c\º$3 1$lhYa/bZhhV\Z3
283
284
CHAPTER
59
Creating and Consuming Web Services
Listing 59.4 shows the two lhYa/bZhhV\Z tags that map to our single operation >ciZ\ZgIdHig^c\. First is the >ciZ\ZgIdHig^c\GZfjZhi message, which contains the lhYa/eVgi tags. These tags are very important to recognize, because they define the input parameter variables and their WSDL data types. EFK
ciZ\ZgIdHig^c\GZfjZhi. The lhYa/eVgi tag’s name is the same as the input parameter or argument for the CFC. In this case, it is cjbZg^XCjbWZg, which is a cjbZg^X ColdFusion type but maps to an mhY/YdjWaZ data type in WSDL. The lhYa/bZhhV\Z and lhYa/eVgi in this example are of the GZfjZhi"gZhedchZ operation type. This is by far the most common operation in a Web service, but it is not the only one possible. Table 59.2 describes possible operation types within a WSDL document. KXYc\ ,0%)
Operation Types in WSDL
NAME
DESCRIPTION
GZfjZhi"gZhedchZ
The Web service can receive a request and return a response.
Hda^X^i"gZhedchZ
The Web service can send a request and wait for a response.
DcZ"lVn
The Web service can receive a message.
Cdi^ÄXVi^dc
The Web service can send a message.
The standard and most common operation type is GZfjZhi"gZhedchZ. If an application server such as ColdFusion has a scheduled task that runs regularly, the server can handle it as a Hda^X^i" gZhedchZ Web service connected to a GZfjZhi"gZhedchZ Web service on the other end. DcZ"lVn and Cdi^ÄXVi^dc types are less common; they are used more often in messaging-based or asynchronous Web services. We will discuss asynchronous Web services briefly in the “Best Practices” section of this chapter. For GZfjZhi"gZhedchZ operations, a Boolean value of igjZ may be returned simply to confirm that a sent request message has indeed been received. Now let’s take a look at the entire WSDL document in Listing 59.5. C`jk`e^ ,0%,
CjbZg^XHig^c\#X[X —The
WSDL for Our Simple Web Service
1lhYa/YZÄc^i^dch iVg\ZiCVbZheVXZ2º]iie/$$T*.#dlhº mbach/VeVX]ZhdVe2º]iie/$$ mba#VeVX]Z#dg\$mba"hdVeº mbach/^bea2º]iie/$$T*.#dlhº mbach/^ci[2º]iie/$$T*.#dlhº mbach/hdVeZcX2º]iie/$$hX]ZbVh#mbahdVe#dg\$hdVe$ZcXdY^c\$º mbach/ich&2º]iie/$$geX#mba# XdaY[jh^dcº mbach/lhYa2º]iie/$$hX]ZbVh#mbahdVe#dg\$lhYa$º mbach/lhYahdVe2º]iie/$$ hX]ZbVh#mbahdVe#dg\$lhYa$hdVe$º mbach/mhY2º]iie/$$lll#l(#dg\$'%%&$MBAHX]ZbVº3 1""LH9A XgZViZY Wn 8daY;jh^dc kZgh^dc .!%!%!'*&%'-""3 1lhYa/ineZh3 1hX]ZbV iVg\ZiCVbZheVXZ2º]iie/$$geX#mba#XdaY[jh^dcº mbach2º]iie/$$lll#l(#dg\$'%%&$ MBAHX]ZbVº3 1^bedgi cVbZheVXZ2º]iie/$$hX]ZbVh#mbahdVe#dg\$hdVe$ZcXdY^c\$º$3 1XdbeaZmIneZ cVbZ2º8;8>ckdXVi^dc:mXZei^dcº3
WSDL
C`jk`e^ ,0%,
(continued)
1hZfjZcXZ$3 1$XdbeaZmIneZ3 1$hX]ZbV3 1$lhYa/ineZh3 1lhYa/bZhhV\Z cVbZ2º8;8>ckdXVi^dc:mXZei^dcº3 1lhYa/eVgi cVbZ2º[Vjaiº ineZ2ºich&/8;8>ckdXVi^dc:mXZei^dcº$3 1$lhYa/bZhhV\Z3 1lhYa/bZhhV\Z cVbZ2º>ciZ\ZgIdHig^c\GZhedchZº3 1lhYa/eVgi cVbZ2º>ciZ\ZgIdHig^c\GZijgcº ineZ2ºmhY/hig^c\º$3 1$lhYa/bZhhV\Z3 1lhYa/bZhhV\Z cVbZ2º>ciZ\ZgIdHig^c\GZfjZhiº3 1lhYa/eVgi cVbZ2ºcjbWZgCjbZg^Xº ineZ2ºmhY/YdjWaZº$3 1$lhYa/bZhhV\Z3 1lhYa/edgiIneZ cVbZ2ºCjbZg^XHig^c\º3 1lhYa/deZgVi^dc cVbZ2º>ciZ\ZgIdHig^c\º eVgVbZiZgDgYZg2ºcjbWZgCjbZg^Xº3 1lhYa/^ceji bZhhV\Z2º^bea/>ciZ\ZgIdHig^c\GZfjZhiº cVbZ2º>ciZ\ZgIdHig^c\GZfjZhiº$3 1lhYa/djieji bZhhV\Z2º^bea/>ciZ\ZgIdHig^c\GZhedchZº cVbZ2º>ciZ\ZgIdHig^c\GZ hedchZº$3 1lhYa/[Vjai bZhhV\Z2º^bea/8;8>ckdXVi^dc:mXZei^dcº cVbZ2º8;8>ckdXVi^dc:mXZei^dcº$3 1$lhYa/deZgVi^dc3 1$lhYa/edgiIneZ3 1lhYa/W^cY^c\ cVbZ2ºCjbZg^XHig^c\#X[XHdVe7^cY^c\º ineZ2º^bea/CjbZg^XHig^c\º3 1lhYahdVe/W^cY^c\ hinaZ2ºgeXº igVchedgi2º]iie/$$hX]ZbVh#mbahdVe#dg\$hdVe$ ]iieº$3 1lhYa/deZgVi^dc cVbZ2º>ciZ\ZgIdHig^c\º3 1lhYahdVe/deZgVi^dc hdVe6Xi^dc2ºº$3 1lhYa/^ceji cVbZ2º>ciZ\ZgIdHig^c\GZfjZhiº3 1lhYahdVe/WdYn ZcXdY^c\HinaZ2º]iie/$$hX]ZbVh#mbahdVe#dg\$hdVe$ZcXdY^c\$º cVbZheVXZ2º]iie/$$T*.#dlhº jhZ2ºZcXdYZYº$3 1$lhYa/^ceji3 1lhYa/djieji cVbZ2º>ciZ\ZgIdHig^c\GZhedchZº3 1lhYahdVe/WdYn ZcXdY^c\HinaZ2º]iie/$$hX]ZbVh#mbahdVe#dg\$hdVe$ZcXdY^c\$º cVbZheVXZ2º]iie/$$T*.#dlhº jhZ2ºZcXdYZYº$3 1$lhYa/djieji3 1lhYa/[Vjai cVbZ2º8;8>ckdXVi^dc:mXZei^dcº3 1lhYahdVe/[Vjai ZcXdY^c\HinaZ2º]iie/$$hX]ZbVh#mbahdVe#dg\$hdVe$ZcXdY^c\$º cVbZ2º8;8>ckdXVi^dc:mXZei^dcº cVbZheVXZ2º]iie/$$T*.#dlhº jhZ2ºZcXdYZYº$3 1$lhYa/[Vjai3 1$lhYa/deZgVi^dc3 1$lhYa/W^cY^c\3 1lhYa/hZgk^XZ cVbZ2ºCjbZg^XHig^c\º3 1lhYa/YdXjbZciVi^dc mbach/lhYa2º]iie/$$hX]ZbVh#mbahdVe#dg\$lhYa$º3 8dckZgih V cjbWZg id ^ih Hig^c\ gZegZhZciVi^dc 1$lhYa/YdXjbZciVi^dc3 1lhYa/edgi W^cY^c\2º^bea/CjbZg^XHig^c\#X[XHdVe7^cY^c\º cVbZ2ºCjbZg^XHig^c\# X[Xº3
285
286
CHAPTER
59
C`jk`e^ ,0%,
Creating and Consuming Web Services
(continued) 1lhYahdVe/VYYgZhh adXVi^dc2º]iie/$$adXVa]dhi$dlh$*.$CjbZg^XHig^c\#X[Xº$3 1$lhYa/edgi3
1$lhYa/hZgk^XZ3 1$lhYa/YZÄc^i^dch3
Now that we have a general idea of what is going on, let’s try to figure out what we would need to know from the WSDL document in order to invoke our example Web service. The first thing we need is the URL for the WSDL document. We used this previously to get the WSDL to display in our browser. Next, we need to determine what the input parameters are and what their data types are. We know from the single 1lhYa/eVgi3 tag within the >ciZ\ZgIdHig^c\GZfjZhi message that the only input parameter is named cjbWZgCjbZg^X, and its XML Schema data type is mhY/YdjWaZ. We now know everything needed in order to call the >ciZ\ZgIdHig^c\ method of the CjbZg^XHig^c\ Web service. We will review this more in the section “Consuming Web Services.” EFK
8:/ IZhiH^beaZ8gZY^iGVi^c\#X[b 9:H8G>EI>DC/ IZhi i]Z 8;8# """3 1""" 8dchigjXi i]Z JGA YncVb^XVaan """3 1XÄ[ cdi ÄcYCd8VhZ¹]iiehº! X\^#hZgkZgTegdidXda3
289
290
CHAPTER
59
C`jk`e^ ,0%/
Creating and Consuming Web Services
(continued)
1X[hZi i]ZJGA 2 ¹]iie/$$º3 1X[ZahZ3 1X[hZi i]ZJGA 2 ¹]iieh/$$º3 1$XÄ[3 1""" 6YY i]Z hZgkZg VcY XjggZci eVi] """3 1X[hZi i]ZJGA 2 i]ZJGA X\^#hZgkZgTcVbZ ¹/º X\^#hZgkZgTedgi X\^#hXg^eiTcVbZ3 1""" Cdl gZbdkZ i]^h ÄaZ¼h cVbZ! l]^X] ^h Vi i]Z ZcY """3 1X[hZi i]ZJGA 2 a^hi9ZaZiZ6ii]ZJGA! a^hiAZci]ZJGA!º$º! ¹$º3 1XÄckd`Z lZWhZgk^XZ2ºi]ZJGA$H^beaZ8gZY^iGVi^c\#X[X4lhYaº bZi]dY2º\Zi8gZY^iGVi^c\º gZijgckVg^VWaZ2ºXgZY^iGVi^c\º3 1XÄckd`ZVg\jbZci cVbZ2ºHHCº kVajZ2º%%%%%%%%&º$3 1$XÄckd`Z3 1X[djieji3I]Z gZhjai ^h/ XgZY^iGVi^c\1$X[djieji3
Most of this script simply creates the i]ZJGA variable. This allows the script to run on any Web server and any directory. The script assumes that it lies in the same directory as the Web service. Once the URL is figured out, the script simply uses the 1XÄckd`Z3 tag to call it. Now let’s take a look at a similar CFC that takes a higjXi data type. While a higjXi is similar to a number of data types in C++ and Java, it does not exactly match any of those defined in the XML Schema used by WSDL and SOAP for data-type representation and conversion. Listing 59.9 shows the Credit Rating Web service, which for its only argument takes a bVe or ColdFusion structure as the data type for its only argument. C`jk`e^ ,0%0
BVe8gZY^iGVi^c\#X[X —Web
Service with higjXi or bVe Data Type
1""" 6JI=DG/ 7gZcYVc D¼=VgV Wd]VgV5ZiZX]hdaji^dch#Xdb L:7 H:GK>8:/ BVe8gZY^iGVi^c\#X[X 9:H8G>EI>DC/ 8daY;jh^dc 8;8 YZeadnZY Vh V LZW HZgk^XZ id gZijgc V 8gZY^i GVi^c\ hig^c\ [dg V eVhhZY"^c ¹EZghdcº higjXi# 6G<JB:CIH/ cVbZ2ºEZghdcº ineZ2ºhigjXiº gZfj^gZY2ºnZhº """3 1X[XdbedcZci djieji2º[VahZº3 1""" LZ YZÄcZ i]Z 8;8¼h h^c\aZ [jcXi^dc i]Vi gZig^ZkZh i]Z XgZY^i gVi^c\ [dg V eVhhZY"^c ¹EZghdcº VcY gZijgch ^i """3 1X[[jcXi^dc cVbZ2º\Zi8gZY^iGVi^c\º djieji2º[VahZº gZijgcIneZ2ºhig^c\º VXXZhh2ºgZbdiZº3 1""" I]Z \Zi8gZY^iGVi^c\ [jcXi^dc iV`Zh V h^c\aZ Vg\jbZci XVaaZY ¹EZghdcº d[ ineZ higjXi! l]^X] ^h gZfj^gZY """3 1X[Vg\jbZci cVbZ2ºEZghdcº ineZ2ºhigjXiº gZfj^gZY2ºnZhº3 1""" kVg hXdeZ i]Z gZhjai """3 1X[hZi kVg gZhjai 2 ¹º3 1""" I]^h ldjaY WZ gZVa ad\^X ]ZgZ """3 1X[hZi gZhjai 2 aZcVg\jbZcih#eZghdc#hhc gVcYGVc\Z*%!&%%3
Creating Web Services
C`jk`e^ ,0%0
(continued)
1""" I]Zc i]Z 8gZY^iGVi^c\ ^h gZijgcZY """3 1X[gZijgc gZhjai3 1$X[[jcXi^dc3 1$X[XdbedcZci3
Other than the data type change, the only thing new here is the fake logic used to return the credit rating. The problem we face is this: When clients other than ColdFusion call this Web service, they will need additional information to convert the arguments to a data type that ColdFusion expects and understands. Let’s look at a portion of the generated WSDL for the bVe8gZY^iGVi^c\ Web service to see what we are talking about. It is displayed in Listing 59.10. C`jk`e^ ,0%('
BVe8gZY^iGVi^c\#X[X —WSDL
Portion with higjXi or bVe Data Type
1lhYa/ineZh3 1hX]ZbV iVg\ZiCVbZheVXZ2º]iie/$$mba#VeVX]Z#dg\$mba"hdVeº mbach2º]iie/$$ lll#l(#dg\$'%%&$MBAHX]ZbVº3 1^bedgi cVbZheVXZ2º]iie/$$T*.#dlhº$3 1^bedgi cVbZheVXZ2º]iie/$$geX#mba#XdaY[jh^dcº$3 1^bedgi cVbZheVXZ2º]iie/$$hX]ZbVh#mbahdVe#dg\$hdVe$ZcXdY^c\$º$3 1XdbeaZmIneZ cVbZ2ºbVe>iZbº3 1hZfjZcXZ3 1ZaZbZci cVbZ2º`Znº c^aaVWaZ2ºigjZº ineZ2ºmhY/VcnIneZº$3 1ZaZbZci cVbZ2ºkVajZº c^aaVWaZ2ºigjZº ineZ2ºmhY/VcnIneZº$3 1$hZfjZcXZ3 1$XdbeaZmIneZ3 1XdbeaZmIneZ cVbZ2ºBVeº3 1hZfjZcXZ3 1ZaZbZci bVmDXXjgh2ºjcWdjcYZYº b^cDXXjgh2º%º cVbZ2º^iZbº ineZ2ºVeVX]ZhdVe/bVe>iZbº$3 1$hZfjZcXZ3 1$XdbeaZmIneZ3 1$hX]ZbV3
This bVe complex type is generated by all uses of the higjXi data type in 1X[[jcXi^dc3 arguments. You will notice that both the `Zn and kVajZ can be of any data type. A call to this Web service will work if it comes from a ColdFusion page, but it’s not the most platform-independent way of accepting structured data. Because ColdFusion doesn’t predefine data types for all variables, we need to be aware of data types that may be problematic. The higjXi or bVe data type common to ColdFusion is not exactly represented in the XML Schema that SOAP uses for automatic datatype translation. Another unsupported data type is fjZgn. That is why we need to limit the use of unsupported data types in Web services when interacting with other platforms.
;\Ôe`e^ :fdgc\o ;XkX Kpg\j Web services may be significantly more complex than our “simple” example, and their input parameters may be custom or unsupported data types. A Web service may need to accept multiple fields, or a single field containing a complex data type, in order to process the called function and return data to the caller. Object-oriented languages such as Java, C++, and C# have direct mappings from their complex data types to the XML Schema data types used by SOAP and WSDL.
291
292
CHAPTER
59
Creating and Consuming Web Services
Unfortunately, ColdFusion doesn’t have direct mappings to many of these complex data types. What it does have is the capacity to let you define your own complex data types using CFCs and the 1X[egdeZgin3 tag. Listing 59.11 shows a CFC completely empty of content except for 1X[egdeZgin3 tags. C`jk`e^ ,0%(( 8gZY^iEZghdc#X[X —Complex Data Type for Use with a Web Service 1""" 6JI=DG/ 7gZcYVc D¼=VgV Wd]VgV5ZiZX]hdaji^dch#Xdb 8DBEDC:CI/ 8gZY^iEZghdc#X[X 9:H8G>EI>DC/ 8daY;jh^dc 8;8 YZeadnZY Vh V XdbeaZm YViV ineZ [dg jhZ l^i] LZW HZgk^XZh# Cd [jcXi^dch# Cd Vg\jbZcih# """3 1X[XdbedcZci3 1X[egdeZgin cVbZ2º;^ghiCVbZº ineZ2ºhig^c\º3 1X[egdeZgin cVbZ2ºAVhicVbZº ineZ2ºhig^c\º3 1X[egdeZgin cVbZ2º6YYgZhhº ineZ2ºhig^c\º3 1X[egdeZgin cVbZ2º8^inº ineZ2ºhig^c\º3 1X[egdeZgin cVbZ2ºHiViZº ineZ2ºhig^c\º3 1X[egdeZgin cVbZ2ºO^e8dYZº ineZ2ºhig^c\º3 1X[egdeZgin cVbZ2ºHHCº ineZ2ºhig^c\º3 1$X[XdbedcZci3
The 1X[egdeZgin3 tag is used for Web services to define a complex data type. In ColdFusion this would be a structure, but because a higjXi is not a supported data type, we use another CFC without arguments to define the structure of our complex data type. The Credit Rating CFC Web service using a complex data type is shown in Listing 59.12. C`jk`e^ ,0%() 8dbeaZm8gZY^iGVi^c\#X[X —Web Service with Complex Data Type 1""" 6JI=DG/ 7gZcYVc D¼=VgV Wd]VgV5ZiZX]hdaji^dch#Xdb L:7 H:GK>8:/ 8dbeaZm8gZY^iGVi^c\#X[X 9:H8G>EI>DC/ 8daY;jh^dc 8;8 YZeadnZY Vh V LZW HZgk^XZ id gZijgc V 8gZY^i GVi^c\ ¹hig^c\º [dg V eVhhZY"^c ¹EZghdcº! l]^X] ^h V 8dbeaZm 9ViV IneZ l]^X] ^h YZÄcZY ^c i]Z 8;8 EZghdc#X[X# 6G<JB:CIH/ cVbZ2ºHHCº ineZ2ºhig^c\º gZfj^gZY2ºnZhº """3 1X[XdbedcZci djieji2º[VahZº3 1""" LZ YZÄcZ i]Z 8;8¼h h^c\aZ [jcXi^dc i]Vi gZig^ZkZh i]Z XgZY^i gVi^c\ [dg V eVhhZY"^c ¹EZghdcº VcY gZijgch ^i """3 1X[[jcXi^dc cVbZ2ºckd`Z i]Z lZW hZgk^XZ """3 1XÄckd`Z lZWhZgk^XZ2ºi]ZJGA$CjbZg^XHig^c\#X[X4lhYaº bZi]dY2º^ciZ\ZgIdHig^c\º cjbWZgCjbZg^X2ºgVcYGVc\Z%!.º gZijgcKVg^VWaZ2ºgZhjaiº3 1X[djieji3GZhjai d[ lZW hZgk^XZ XVaa/ gZhjai1$X[djieji3 1e3 1""" cdl Yd V h^beaZ 8;8 XVaa """3 1XÄckd`Z XdbedcZci2ºCjbZg^XHig^c\º bZi]dY2º^ciZ\ZgIdHig^c\º cjbWZgCjbZg^X2ºgVcYGVc\Z%!.º gZijgcKVg^VWaZ2ºgZhjaiº3 1X[djieji3GZhjai d[ XdbedcZci XVaa/ gZhjai1$X[djieji3
Once again, the script starts by figuring out the current root URL. After that, we use 1XÄckd`Z3 to call the CjbZg^XHig^c\ Web service. We tell the tag which method to execute, and we pass in the cjbWZgCjbZg^X attribute. Lastly, we tell the 1XÄckd`Z3 tag to return the result in a variable called gZhjai. The next use of 1XÄckd`Z3 calls the exact same code, except this time it is used as a ColdFusion component.
:fdgc\o ;XkX Kpg\j As we discussed previously, a complex data type can be described as a data type that represents multiple values. Arrays, record sets, and structures are good examples of complex data types. Although
297
298
CHAPTER
59
Creating and Consuming Web Services
these are relatively easy to visualize and describe, representing them programmatically among different application servers on different platforms presents a formidable obstacle. SOAP saves us from having to code our Web services to accommodate every server’s interpretation of every data type. This is accomplished by defining SOAP-specific data types that are a workable subset of common data types. The most that developers must do is plug their variables into the appropriate SOAP data types. Each application is responsible for translating to and from the SOAP data types. CFML contains several of these complex data types. As part of consuming Web services, you will need to know how ColdFusion converts WSDL-defined data types to ColdFusion data types and vice versa. In order to facilitate their uses in CFCs exposed as Web services, ColdFusion maps certain objects to their corresponding SOAP data types completely behind the scenes. Table 59.3 shows this mapping. KXYc\ ,0%*
WSDL-to-ColdFusion Data Type Conversion
WSDL DATA TYPE
COLDFUSION DATA TYPE
HD6E":C8/YdjWaZ
cjbZg^X
HD6E":C8/WddaZVc
WddaZVc
HD6E":C8/hig^c\
hig^c\
HD6E":C8/6ggVn
VggVn
mhY/WVhZ+)7^cVgn
W^cVgn
mhY/ÅdVi
cjbZg^X
mhY/ZcjbZgVi^dc
hig^c\
mhY/YViZI^bZ
YViZ
ich&/FjZgn7ZVc
fjZgn
kd^Y
Nothing is returned
Other complex type
structure
* These types do convert between ColdFusion and other SOAP implementations and are not supported directly by WSDL.
@emfZXk`fe n`k_ :fc[=lj`fe 9l`c[\i When you add a Web service via the ColdFusion Builder Services Browser, ColdFusion Builder reads the WSDL document so that it can generate the invocation code for you. You never have to read the WSDL yourself! Figure 59.1 shows the Services Browser user interface for adding a Web service (to get to this dialog box, click the Show Web Services button in the Services Browser to see Web services that have been added and then click the red button). You point the ColdFusion Builder Services Browser to a WSDL document. ColdFusion Builder analyzes the WSDL and displays all the methods, and the arguments for each, supported by the Web service. To invoke a Web service method, place your cursor in your ColdFusion code at the location where you want the invocation code inserted and then, keeping the code window visible, right-click in the Services Browser on the name of the method you want to invoke and choose either Insert CFInvoke or Insert CreateObject from the menu that appears.
Consuming Web Services
=`^li\ ,0%( ColdFusion Builder Services Browser User Interface.
@emfb`e^ %E\e\iXk\[ NJ;C As you can probably imagine, the task of generating WSDL for a Web service takes time. Because of this, ColdFusion caches the WSDL generated by the Web service after the first time it is generated. There are two ways to deal with this. The ColdFusion Administrator provides a simple button you can use to refresh the WSDL generated by a Web service call. Also, the XÄckd`Z tag supports a gZ[gZh]LH9A attribute that you can use to force ColdFusion to refresh its WSDL definition. Another useful feature of XÄckd`Z in ColdFusion is lhYa'?VkV6g\h. If you are familiar with the WSDL2 Java tool that allows ColdFusion users to generate WSDL, you can specify a spacedelimited set of arguments that will be passed to this tool when XÄckd`Z is used. Most folks will never need to use this attribute, though.
299
300
CHAPTER
59
Creating and Consuming Web Services
Nfib`e^ n`k_ JF8G I\hl\jkj ColdFusion offers a variety of ways to work with the SOAP requests and responses involved in Web services. Let’s start with a simple example. As discussed earlier, for a component to be used as a Web service, it must have at least one method with VXXZhh2ºgZbdiZº. This same method, however, can be called by other ColdFusion templates on the server. It can also be called via Flash Remoting. What if you want to ensure that the method is only called as a Web service? ColdFusion has a function, ^hHdVeGZfjZhi, that returns igjZ if the current method was executed as a Web service. Listing 59.18 demonstrates a simple Web service with a method that can only be called as a Web service. C`jk`e^ ,0%(/ _jhiVlZWhZgk^XZ#X[X—A Web-Service-Only Component 1X[XdbedcZci3 1X[[jcXi^dc cVbZ2ºiZhiº gZijgcineZ2ºhig^c\º VXXZhh2ºgZbdiZº3 1XÄ[ ^hHdVeGZfjZhi3 1X[gZijgc ¹ XdjaYc¼i XVaa i]Z bZi]dY# 1$X[XViX]3 1$X[ign3
As in the other templates we have used, the script begins by determining the current URL. Once past that, we invoke the Web service method and then call the same method as a local CFC. Since we know this isn’t going to work, we wrap it in a 1X[ign31X[XViX]3 block. When run, the Web service will return a good result, while the local CFC invocation will throw an error.
:Xcc`e^ N\Y J\im`Z\j n`k_ E`ccXYc\ 8i^ld\ekj When building a method, any combination of arguments can be used to define its behavior. Some Web services may define a method as having “nillable” arguments. This simply means the value can be null. However, ColdFusion doesn’t allow you to create null values. Thus in earlier versions of ColdFusion it was impossible to call these Web services. An argument, db^i, can be used in 1XÄckd`ZVg\jbZci3 to pass a null value to a Web service. Listing 59.19 demonstrates a simple Web service with an optional argument (this will act as a nillable argument). C`jk`e^ ,0%(0
C^aaVWaZLH#X[X —Nillable
CFC Example
1X[XdbedcZci3 1X[[jcXi^dc cVbZ2ºiZhiº gZijgcineZ2ºhig^c\º VXXZhh2ºgZbdiZº3 1X[Vg\jbZci cVbZ2ºVae]Vº ineZ2ºhig^c\º gZfj^gZY2ºigjZº3 1X[Vg\jbZci cVbZ2ºWZiVº ineZ2ºhig^c\º gZfj^gZY2º[VahZº3 1X[Vg\jbZci cVbZ2ºXVgcnº ineZ2ºhig^c\º gZfj^gZY2ºigjZº3 1X[gZijgc ¹;ddº3 1$X[[jcXi^dc3 1$X[XdbedcZci3
This is an extremely simple Web service. The test method has three arguments. The second argument, WZiV, is marked as optional. Listing 59.20 demonstrates how we can correctly call this Web service. C`jk`e^ ,0%)' IZhiC^aaVWaZ#X[b —Testing C^aaVWaZLH#X[X 1""" 8dchigjXi i]Z JGA YncVb^XVaan """3 1XÄ[ cdi ÄcYCd8VhZ¹]iiehº! X\^#hZgkZgTegdidXda3 1X[hZi i]ZJGA 2 ¹]iie/$$º3 1X[ZahZ3 1X[hZi i]ZJGA 2 ¹]iieh/$$º3 1$XÄ[3 1""" 6YY i]Z hZgkZg VcY XjggZci eVi] """3 1X[hZi i]ZJGA 2 i]ZJGA X\^#hZgkZgTcVbZ ¹/º X\^#hZgkZgTedgi X\^#hXg^eiTcVbZ3 1""" Cdl gZbdkZ i]^h ÄaZ¼h cVbZ! l]^X] ^h Vi i]Z ZcY """3
301
302
CHAPTER
59
C`jk`e^ ,0%)'
Creating and Consuming Web Services
(continued)
1X[hZi i]ZJGA 2 a^hi9ZaZiZ6ii]ZJGA! a^hiAZci]ZJGA!º$º! ¹$º3 1XÄckd`Z lZWhZgk^XZ2ºi]ZJGA$C^aaVWaZLH#X[X4lhYaº bZi]dY2ºiZhiº gZijgcKVg^VWaZ2ºgZhjaiº3 1XÄckd`ZVg\jbZci cVbZ2ºVae]Vº kVajZ2º[ddº3 1XÄckd`ZVg\jbZci cVbZ2ºWZiVº db^i2ºnZhº3 1XÄckd`ZVg\jbZci cVbZ2ºXVgcnº kVajZ2ºbddº3 1$XÄckd`Z3 1X[djieji3GZhjai ^h gZhjai1$X[djieji3
As with our numerous other examples, we begin by simply grabbing the current URL dynamically. We then invoke the C^aaVWaZLH Web service. This Web service takes three arguments, with the middle argument, WZiV, being optional. By default, you cannot omit this argument, even though the method was defined as optional. With ColdFusion, however, we can pass in the argument and use db^i2ºnZhº to pass a null value to the Web service. Think of this as a simple way of passing a null value, which ColdFusion doesn’t natively support.
9\jk GiXZk`Z\j As with many technologies, architectures, and strategies, Web services have generated significant hype. Along with the advantages of cross-platform compatibility come some drawbacks. Although the distributed computing environment of Web services is widely recognized as the way of the future, it carries the baggage of network latency and additional translation time. The actual overhead of running a Web service is not as bad as perceived, but it is a factor for system architects to consider when selecting parts of their systems to expose to the world. Careful testing and optimization can reduce this potential problem significantly. Here are several general principles to consider when programming and architecting Web services: N
Use coarse-grained Web services. Do not call the same Web service 10 times on a page. Call it once and use a query of queries to return the granular information for display. Return the appropriate amount of information based on the transaction overhead.
N
Use stateless Web services whenever possible.
N
Limit the use of complex data types within a Web service when interacting with other platforms.
Another practice that is highly recommended is the use of asynchronous Web services. Synchronous RPC-style operations let you know immediately whether an operation was successful. Performing synchronous operations across multiple processes is an all-or-nothing proposition. The initiating application must wait for the chain of GZfjZhi"gZhedchZ operations, regardless of its length. When something goes down or a process fails, the application initiating the request must know to take some other course of action. On the other hand, asynchronous messaging allows a process to be concerned only with initiating a request, knowing that it will eventually receive a response asynchronously. This relieves the Web service client from waiting for the
Best Practices
invoked operation to respond. The DcZ"lVn and Hda^X^iVi^dc operation types are commonly used with asynchronous Web services. These should be used for performance reasons, when available from Web services providers, whenever immediate responses are not required.
ckdXVi^dc· :mXZei^dc that ColdFusion creates when generating the WSDL for your Web service. This allows someone who calls a Web service you have written to catch run-time or other errors while their code continues processing without the expected response from your Web service. Any Web service can throw errors, which may or may not be critical to the page that is calling the service. If you use 1X[ign3 and 1X[XViX]3 or the ign, XViX] 1X[hXg^ei> equivalents, you can catch CFC, SOAP, and other errors in your application. If you don’t catch these errors, they will be displayed in the browser. Unless you’re testing the Web service yourself, you probably don’t want the error to be written to the screen. Catching errors in ColdFusion is not difficult, but it does take some effort. You can catch multiple types of errors that may all require various types of additional processing. You can also specify an error type of Vcn, which acts as a catch-all to the ColdFusion <X[XViX]3 tag, as shown in Listing 59.21. C`jk`e^ ,0%)( ignXViX]TZmVbeaZ#X[b —Sample Use of 1X[ign31X[XViX]3 While Invoking a Web Service 1X[ign3 1XÄckd`Z bZi]dY2º=IBAHZVgX]6YYgZhhº gZijgckVg^VWaZ2ºVHig^c\º lZWhZgk^XZ2 ¹]iie/$$lll#bVgdio#hZ$hXg^eih$hZVgX]eZghdc#ZmZ$lhYa$>HZVgX]HlZY^h]EZghdcº3 1XÄckd`ZVg\jbZci cVbZ2º[CVbZº kVajZ2ºHkZcº$3 1XÄckd`ZVg\jbZci cVbZ2ºaCVbZº kVajZ2ºHkZchhdcº$3 1XÄckd`ZVg\jbZci cVbZ2ºVYYgZhhº kVajZ2ºº$3 1XÄckd`ZVg\jbZci cVbZ2ºo^e8dYZº kVajZ2ºº$3 1XÄckd`ZVg\jbZci cVbZ2ºX^inº kVajZ2ºº$3 1$XÄckd`Z3 1X[XViX] ineZ2ºVcnº3 1X[hZi Vhig^c\ 2 ¹L]ZgZ ^c i]Z ldgaY ^h HkZc HkZchhdc4º3 1$X[XViX]3 1$X[ign3 1X[djieji3VHig^c\1$X[djieji3
:feÔ^li`e^ N\Y J\im`Z\j `e k_\ :fc[=lj`fe 8[d`e`jkiXkfi The ColdFusion Administrator lets you register a Web service with a name and URL. When you reference that Web service later in your code, you won’t have to specify the URL for the Web service’s WSDL file. Instead, the Web service can be referenced using the name that points to the WSDL’s URL. For example, anytime you invoke a Web service registered as O^e8dYZLH on a particular server, you reference it as LZWHZgk^XZ2ºO^e8dYZLHº. The URL can then be changed to point to another URL without modifying the invocation code throughout the application. This represents a type of code encapsulation, which could also be done using 6EEA>86I>DC or G:FJ:HI scope variables.
303
This page intentionally left blank
:?8GK! 8ViZ\dgnAVWZa! 8ViZ\dgnHX]ZbZ! 8ViZ\dgnIZgb! 8dbbZcih! 8dciZci! 8dciZciBdYZ! 8dciZciHgX! 8dciZciIneZ! 8dcig^Wjidg:bV^a! 8dcig^WjidgCVbZ! 8dcig^WjidgJG>! 8gZViZY9ViZ! :me^gVi^dc9ViZ! >9! >9EZgbVa^c`! A^c`=gZ[! A^c`=gZ[AVc\! A^c`AZc\i]! A^c`GZa! A^c`I^iaZ! A^c`IneZ! EjWa^h]ZY9ViZ! G^\]ih! GHHA^c`! HdjgXZ! HdjgXZJGA! HjbbVgn! HjbbVgnBdYZ! HjbbVgnHgX! HjbbVgnIneZ! I^iaZ! I^iaZIneZ! JeYViZY9ViZ! JG>! MBA7VhZ
Lj`e^ ;lYc`e :fi\ Xe[ `Kle\j [ i]Z gZXdgY gZegZhZcih V hjW[daYZg! a^hi ^i Vh Vc dei^dc """3 1XÄ[ IneZ Zf ¹9^gº3 1dei^dc kVajZ2ºhjW[daYZgEVi]$CVbZº3CVbZ1$dei^dc3 1$XÄ[3 1$XÅdde3 1$hZaZXi3 1""" HjWb^i Wjiidc id cVk^\ViZ id i]Z hZaZXiZY [daYZg """3 1^ceji ineZ2ºhjWb^iº kVajZ2º\dº3 1$[dgb3
1""" JhZ FjZgn d[ FjZg^Zh >c BZbdgn FjZgn id \Zi V hjWhZi d[ """3 1""" i]Z fjZgn gZijgcZY Wn 1X[Y^gZXidgn3# I]^h cZl fjZgn dW_ZXi """3 1""" l^aa ]daY dcan i]Z ÄaZ gZXdgYh! cdi Vcn hjW[daYZg gZXdgYh """3 1X[fjZgn YWineZ2ºfjZgnº cVbZ2ºÄaZhFjZgnº3 H:A:8I ;GDB Y^gZXidgnFjZgn L=:G: INE: 2 »;^aZ¼ 1$X[fjZgn3
1""" >[ i]ZgZ ^h Vi aZVhi dcZ ÄaZ id Y^heaVn### """3 1XÄ[ ÄaZhFjZgn#gZXdgY8djci \i %3 1""" 9^heaVn i]Z ÄaZh ^c V h^beaZ =IBA iVWaZ """3 1iVWaZ l^Yi]2º*%%º WdgYZg2º%º XZaaEVYY^c\2º&º XZaaHeVX^c\2º%º3 1ig W\Xdadg2ºXdgcÅdlZgWajZº3 1i]3;^aZcVbZ1$i]3 1i]3BdY^ÄZY1$i]3 1i]3H^oZ1$i]3 1$ig3 1""" ;dg ZVX] ÄaZ### """3 1XÅdde fjZgn2ºÄaZhFjZgnº3 1""" JhZ VaiZgcVi^c\ Xdadgh [dg i]Z iVWaZ gdlh """3 1XÄ[ ÄaZhFjZgn#XjggZciGdl bdY ' Zf %3 1X[hZi gdl8dadg 2 ¹a^\]i\gZnº3 1X[ZahZ3 1X[hZi gdl8dadg 2 ¹l]^iZº3 1$XÄ[3 1""" 9^heaVn i]Z ÄaZ YZiV^ah """3 1ig W\Xdadg2ºgdl8dadgº3 1""" ;^aZ cVbZ """3 1iY l^Yi]2º'*%º3 CVbZ 1$iY3 1""" ;^aZ bdY^ÄXVi^dc YViZ VcY i^bZ """3 1iY l^Yi]2º'%%º3
339
340
CHAPTER
61
C`jk`e^ -(%(+
Interacting with the Operating System
(continued)
YViZ;dgbVi9ViZAVhiBdY^ÄZY! ¹b$Y$nnnnº Vi i^bZ;dgbVi9ViZAVhiBdY^ÄZY! ¹]/bb/hh iiº 1$iY3 1""" ;^aZ h^oZ """3 1iY l^Yi]2º*%º Va^\c2ºg^\]iº3 XZ^a^c\H^oZ $ &%') @7 1$iY3 1$ig3 1$XÅdde3 1$iVWaZ3 1$XÄ[3 1$WdYn3 1$]iba3 1$X[djieji3
First, the ZmeVcYEVi] function is used to create a variable called WVhZ;daYZg that holds the path to the dlh folder on your server’s drive. The actual value of this variable when your page executes will likely be X/QXdaY[jh^dc.QlllgddiQdlh, X/Q^cZiejWQlllgddiQdlh, or something similar, depending on the Web server you’re using. For common sense security reasons, the user will only be able to explore files and directories within the WVhZ;daYZg. If you want the user to be able to explore some other folder, perhaps outside of your server’s document root, you can hard-code the WVhZ;daYZg variable with the location of that folder. Next, the 1X[eVgVb3 tag is used to declare a variable named hjW[daYZgEVi] and give it a default value of an empty string. This variable will indicate which subfolder within the WVhZ;daYZg that the user wants to explore. If a jga or [dgb parameter called hjW[daYZgEVi] is provided to the page, that value will be used; otherwise it’s assumed that the page is appearing for the first time. If the user has selected the subfolder named images, then the value of hjW[daYZgEVi] will be $^bV\Zh. The [daYZgId9^heaVn variable is then created by concatenating the WVhZ;daYZg together with the hjW[daYZgEVi]. This variable, then, holds the full path to the folder the user wants to explore; this is what will be supplied to the 1X[Y^gZXidgn3 tag to obtain the contents of the folder. So if the user has selected the subfolder named images, the value of [daYZgId9^heaVn will be X/QXdaY[jh^dc.Q lllgddiQdlhQ^bV\Zh,X/Q^cZiejWQlllgddiQdlhQ^bV\Zh, or something similar, depending on what ColdFusion edition or Web server you are using. Now the 1X[Y^gZXidgn3 tag can be used to get a listing of all the files and subfolders within the selected folder. This will result in a query object called Y^gZXidgnFjZgn, which will contain the columns listed in Table 61.7. Near the middle of this listing, a 1XÅdde3 tag is used to loop over the Y^gZXidgnFjZgn query, generating an 1dei^dc3 tag for each subfolder within the current folder. Within the loop, a 1XÄ[3 test is used to only output options for rows where the IneZ column is set to 9^g. This step is necessary because the query object may contain rows for subfolders and other rows for individual files. The 1XÄ[3 test effectively filters the query object so that only rows that represent folders are processed.
Working with Virtual Files
Another way to filter a directory query object by type (that is, to only include files or folders) is to use ColdFusion’s Query of Queries feature (also called In Memory Query). This strategy is used in the second half of this listing, to create a filtered version of Y^gZXidgnFjZgn (called ÄaZhFjZgn) that only contains records for files, not subfolders. Once that’s done, outputting the actual information about files is simple. A 1XÅdde3 block is used to output the file information in a simple HTML table, displaying the values of each record’s CVbZ, H^oZ, and 9ViZAVhiBdY^ÄZY columns. Note that the ordinary YViZ;dgbVi, i^bZ;dgbVi, and XZ^a^c\ functions are used to display the data attractively.
Nfib`e^ n`k_ M`iklXc =`c\j So far, we’ve discussed how you can use various ColdFusion tags and functions to work with files and directories on the server’s file system. From time to time, applications need to work with files of a temporary nature. For example, you may allow someone to upload a file to be used for a profile picture. The file is uploaded to a temporary folder (hopefully outside the Web root!) and checked to see if the file contains a valid image. After that is confirmed, the image can be resized. Finally, the image is moved to its permanent location somewhere under the Web server root so everyone can see it. So here’s the question: While the file is being checked and resized, does it need to actually exist on the file system? The answer is no. ColdFusion 9 introduces the concept of a completely virtual file system. This feature, called both in-memory files and the virtual file system (VFS), is a RAM-based file system. In every way, it acts like a real file system, but the actual data of the files is stored in your server’s RAM. How do you use this file system? In general, nothing special is needed to make use of it. You do have to ensure that it is enabled, though. The ColdFusion Administrator Settings page contains a new setting, Enable In-Memory File System. This must be enabled to make use of the new file system. Also notice that there is a limit to the total amount of data you can put on this file system. The total is configurable in the Administrator and defaults to 100 megabytes. Luckily, both of these settings are available via ColdFusion itself. This means that you can write code that uses the virtual file system only if it is actually enabled. After you’ve determined that you can use the in-memory file system, the only change you need to make is to use the gVb/$$ path as the root of your file or directory operations. So a real file may have a path that looks like this: $A^WgVgn$LZWHZgkZg$YdXjbZcih$[dd#X[b
And a virtual file would have a path that looks like this: gVb/$$$iZbeVeea^XVi^dcÄaZh$^bV\ZjeadVYh$[dd#_e\
Essentially, the use of gVb/$$ signifies that the path that follows is virtual and not one that exists on a physical disk. Listing 61.15 demonstrates a simple example that reads from and writes to the virtual file system.
341
342
CHAPTER
61
C`jk`e^ -(%(,
Interacting with the Operating System
k[h[b —Working
with the Virtual File System
1""" ;^aZcVbZ/ k[h[b 6ji]dg/ GVnbdcY 8VbYZc EjgedhZ/ 9ZbdchigViZh i]Z k^gijVa ÄaZ hnhiZb# """3 1X[hZi bn;^aZ 2 ¹gVb/$$$dlhÄaZh$iZhi#imiº3 1X[hZi bn;daYZg 2 \Zi9^gZXidgn;gdbEVi]bn;^aZ3 1XÄ[ cdi Y^gZXidgn:m^hihbn;daYZg3 1X[Y^gZXidgn VXi^dc2ºXgZViZº Y^gZXidgn2ºbn;daYZgº3 1$XÄ[3 1XÄ[ cdi ÄaZ:m^hihbn;^aZ3 1X[djieji3 1e3 I]Z ÄaZ! bn;^aZ! ^h XjggZcian Zbein#1Wg$3 GZadVY i]^h eV\Z 1$e3 1$X[djieji3 1X[ZahZ3 1X[hZi XdciZcih 2 ÄaZGZVYbn;^aZ3 1X[djieji3 1egZ3 XdciZcih 1$egZ3 1$X[djieji3 1$XÄ[3 1""" 6eeZcY V iZmi bZhhV\Z id i]Z ÄaZ """3 1X[ÄaZ VXi^dc2ºVeeZcYº ÄaZ2ºbn;^aZº djieji2ºIZbe hij[[ lg^iiZc id ÄaZ dc cdlº3
Listing 61.15 begins by defining the path to our virtual file. The decision to use dlhÄaZh as a folder was somewhat arbitrary, but remember that since the virtual file system uses RAM, all templates on the server will share it. We first check to see whether the folder exists. If it doesn’t, the folder is created. Next we see if the file exists. If it does, it is read in and displayed. Finally we append a simple message to the end of the file. It is important to note that almost nothing about this template is any different from the template for a “normal” file or directory. The one single thing special is that use of the gVb/$$ path. As mentioned earlier, it is possibly to programmatically tell whether the virtual file system is enabled, as well as how large it can be, how much is being used, and how much space is left. Listing 61.16 is a modified version of the file explorer in Listing 61.14. What’s incredible is that the main modification (switching from a real file system to a virtual one) was accomplished with this one line: 1X[hZi WVhZ;daYZg 2 ¹gVb/$$º3
C`jk`e^ -(%(- k[hZmeadgZg#X[b —Exploring the Virtual File System 1""" ;^aZcVbZ/ k[hmeadgZg#X[b 6ji]dg/ CViZ LZ^hh CBL! bdY^ÄZY Wn GVn
Working with Virtual Files
C`jk`e^ -(%(-
(continued)
EjgedhZ/ Egdk^YZh Vc ^ciZg[VXZ [dg Zmeadg^c\ ÄaZh VcY hjW[daYZgh l^i]^c i]Z dlh gddi """3 1X[hZi k[h>c[d 2 \ZiK;HBZiV9ViV¹gVbº3 1XÄ[ cdi k[h>c[d#ZcVWaZY3 1e3 Hdggn! Wji i]Z k^gijVa ÄaZ hnhiZb ^h cdi ZcVWaZY 1$e3 1X[VWdgi3 1$XÄ[3 1X[hZi WVhZ;daYZg 2 ¹gVb/$$º3 1X[eVgVb cVbZ2ºhjW[daYZgEVi]º ineZ2ºhig^c\º YZ[Vjai2ºº3 1X[hZi [daYZgId9^heaVn 2 WVhZ;daYZg hjW[daYZgEVi]3 1X[Y^gZXidgn Y^gZXidgn2º[daYZgId9^heaVnº cVbZ2ºY^gZXidgnFjZgnº hdgi2ºCVbZ 6H8º ÄaiZg2ºº3 1X[djieji3 1]iba3 1]ZVY31i^iaZ3K^gijVa ;^aZ :meadgZg1$i^iaZ31$]ZVY3 1WdYn3 1](3K^gijVa ;^aZ :meadgZg1$](3 1e3 I]Z k^gijVa ÄaZ hnhiZb ]Vh V a^b^i cjbWZg;dgbVik[h>c[d#a^b^i WniZh VcY ^h XjggZcian jh^c\ cjbWZg;dgbVik[h>c[d#jhZY WniZh# I]ZgZ VgZ cjbWZg;dgbVik[h>c[d#[gZZ WniZh aZ[i# 1$e3 1[dgb VXi^dc2ºk[hZmeadgZg#X[bº bZi]dY2ºedhiº3 1XÄ[ hjW[daYZgEVi] :F ¹º3 Ndj VgZ Vi i]Z ide aZkZa#1Wg3 1X[ZahZ3 8jggZci ;daYZg/ hjW[daYZgEVi]1Wg3 1$XÄ[3 HZaZXi [daYZg/ 1hZaZXi cVbZ2ºhjW[daYZgEVi]º dcX]Vc\Z2ºi]^h#[dgb#hjWb^iº3 1XÄ[ a^hiAZchjW[daYZgEVi]! ¹$º \i %3 1X[hZi eVgZci;daYZg 2 a^hi9ZaZiZ6ihjW[daYZgEVi]! a^hiAZchjW[daYZgEVi]! ¹$º! ¹$º3 1dei^dc kVajZ2ºeVgZci;daYZgº3PeVgZci [daYZgR1$dei^dc3 1$XÄ[3 1XÅdde fjZgn2º9^gZXidgnFjZgnº3 1XÄ[ IneZ Zf ¹9^gº3 1dei^dc kVajZ2ºhjW[daYZgEVi]$CVbZº3CVbZ1$dei^dc3 1$XÄ[3 1$XÅdde3
343
344
CHAPTER
61
C`jk`e^ -(%(-
Interacting with the Operating System
(continued)
1$hZaZXi3 1^ceji ineZ2ºhjWb^iº kVajZ2º\dº3 1$[dgb3 1X[fjZgn YWineZ2ºfjZgnº cVbZ2ºÄaZhFjZgnº3 H:A:8I ;GDB Y^gZXidgnFjZgn L=:G: INE: 2 »;^aZ¼ 1$X[fjZgn3 1XÄ[ ÄaZhFjZgn#gZXdgY8djci \i %3 1iVWaZ l^Yi]2º*%%º WdgYZg2º%º XZaaEVYY^c\2º&º XZaaHeVX^c\2º%º3 1ig W\Xdadg2ºXdgcÅdlZgWajZº3 1i]3;^aZcVbZ1$i]3 1i]3BdY^ÄZY1$i]3 1i]3H^oZ1$i]3 1$ig3 1XÅdde fjZgn2ºÄaZhFjZgnº3 1XÄ[ ÄaZhFjZgn#XjggZciGdl bdY ' Zf %3 1X[hZi gdl8dadg 2 ¹a^\]i\gZnº3 1X[ZahZ3 1X[hZi gdl8dadg 2 ¹l]^iZº3 1$XÄ[3 1ig W\Xdadg2ºgdl8dadgº3 1iY l^Yi]2º'*%º3 CVbZ 1$iY3 1iY l^Yi]2º'%%º3 YViZ;dgbVi9ViZAVhiBdY^ÄZY! ¹b$Y$nnnnº Vi i^bZ;dgbVi9ViZAVhiBdY^ÄZY! ¹]/bb/hh iiº 1$iY3 1iY l^Yi]2º*%º Va^\c2ºg^\]iº3 XZ^a^c\H^oZ $ &%') @7 1$iY3 1$ig3 1$XÅdde3 1$iVWaZ3 1$XÄ[3 1$WdYn3 1$]iba3 1$X[djieji3
In addition to the change to the WVhZ;daYZg variable, the code used a \ZiK;HBZiV9ViV call. This function takes one parameter, which must always be G6B . It returns a structure of information about the virtual file system. Keys include ZcVWaZY, a^b^i, [gZZ, and jhZY. The ZcVWaZY key is used in the listing to check whether the virtual system can be browsed at all. Later, the a^b^i, [gZZ, and jhZY keys are used to display the space usage for the system.
Executing Programs on the Server with
CI3 tag and its related features. In this chapter, we’ll look at how 18;EG>CI3 enables the printing of PDF documents from ColdFusion. These can be static files or PDFs created using ColdFusion tags such as 18;9D8JB:CI3 and 18;E9;3. We’ll also review related features such as the \ZiEg^ciZg>c[d function and the ColdFusion Administrator’s System Information page, which allow us to retrieve information about available printers and their capabilities for use in 18;EG>CI3, using X[eg^ci#ad\ and using 18;I=G:693.
Fm\im`\n There are many ways to create PDF files in ColdFusion, whether in the latest release or in previous ones. ColdFusion makes it very easy to manipulate PDF documents using tags such as 18;E9;3 and 18;E9;;DGB3. You can even create interactive PDF forms with a combination of 18;;DGB3 and 18;9D8JB:CI3 or by way of Document Description XML (DDX) used by Adobe LiveCycle Assembler or the 18;E9;3 tag. ColdFusion also offers various means of creating PDFs, including building them dynamically from CFML using 18;9D8JB:CI3 and with ColdFusion Report Builder and 18;G:EDGI3.
356
CHAPTER
62
Server-Side Printing
Further, developers have long found third-party solutions to help build PDFs. Also, static PDF files may exist or be created on the server by other means. They can be created by other processes on the server, or be placed on the server by some other operation, or even be uploaded to the server by end users. Whatever the situation, a common requirement is the capability to print the document on a printer attached to the server, and 18;EG>CI3 makes this possible. allows a developer to control the number of pages printed, the size of paper used for printing, whether to print in color, and more. In fact, you can control any printing options that a given printer supports, including stapling, multiple pages per side, rotation, orientation, scaling, and print quality. You can also provide a password for encrypted pages. And with the power of the new 18;I=G:693 tag, you can even spool a print task to be processed asynchronously so that the CFML page launching the print job need not wait for its completion and risk timing out.
18;EG>CI3
Here are just a few possible scenarios that can make use of server-side printing: N
Generate order sheets when online orders are placed.
N
Generate invoices, packing slips, testing documents, and legal documents.
N
Manage electronic medical records and insurance claims and generate such documents on demand or as nightly reports.
One user described another scenario: Imagine a college (or similar institution) offering a means for its applicants to file online the necessary forms, references, cover letters, and so on; then all that information is printed for review when applications are considered. Though the printer must be defined on or be accessible to the server running ColdFusion, it doesn’t necessarily have to be physically attached to it. It could be connected via the network, including a WAN. This means it could enable N
Printing to a remote printer in another location that is connected to the server network via IP address, such as a remote warehouse
N
Printing to a broadcast printer, which in turn prints at several different workstation printers
Again, because we’re talking about printing to a server-side printer and not an end user’s printer, this doesn’t involve integration with the browser, which eliminates some common challenges. The simplicity of 18;EG>CI3 will be a welcome alternative to those who have previously created a concoction of steps such as use of 18;:M:8JI:3 and of batch files to open Acrobat Reader to effect PDF printing.
Lj`e^ 18;EG>CI3 The simplest form of syntax for 18;EG>CI3 is as follows: 1X[eg^ci hdjgXZ2ºhdbZÄaZ#eY[º3
Controlling Printer Capabilities
The hdjgXZ attribute points to a file, and unlike other 18;;>A:3 actions, the hdjgXZ attribute can name either a relative or absolute path. A relative path would be relative to the page issuing the tag. The hdjgXZ attribute could also point to a variable holding the result of some previous ColdFusion tag that created, read in, or manipulated a PDF.
Gi`ek`e^ kf k_\ ;\]Xlck Gi`ek\i The simplest form of 18;EG>CI3 sends the named file (or a variable value, if used) to the default printer—that is, the default printer for the operating system account running ColdFusion. How do you find out what that default printer is and how to refer to it? There are at least two ways. First, the ColdFusion Administrator page, System Information, has a section called Printer Details that lists the default printer along with the names of all available printers. Also, the function \ZiEg^ciZg>c[d can be called with the name of one of those printers as its argument, or it can be called with no argument, in which case it returns information about the default printer. In either case, the structure it returns contains several keys, one of which is the eg^ciZg key, which displays the name of the selected printer. Therefore, the following line of code can be used to quickly and easily show what the system reports to be the default printer, if any: 1X[Yjbe kVg2º\Zieg^ciZg^c[d#eg^ciZgº3
The features for obtaining additional information about printers will be discussed further throughout this chapter.
Gi`ek`e^ kf 8efk_\i Gi`ek\i Although the simple example just presented printed to the default printer, you can print just as easily to another printer if you know its name. You learned in the last section that the ColdFusion Administrator offers a way to see the names of available printers. If you have a printer on your server called HP LaserJet 2200 Series PCL 6, you can print the same document to it using this code: 1X[eg^ci hdjgXZ2ºhdbZÄaZ#eY[º eg^ciZg2º=E AVhZg?Zi ''%% HZg^Zh E8A +º3
If instead you want to print to an available network printer named NTN-2W-HP_BW02 as found on server s1001prn02, you can print to it by forming a UNC path for the server and printer, as follows: 1X[eg^ci hdjgXZ2ºhdbZÄaZ#eY[º eg^ciZg2ºQQh&%%&egc%'QCIC"'L"=ET7L%'º3
EFK
CI3 tag, but most printers offer a wide range of capabilities to more precisely control the appearance of the printed page.
357
358
CHAPTER
62
Server-Side Printing
Some of these capabilities are generic (number of copies to print, pages to print, and so on), and others are printer specific. This section introduces these kinds of printer control capabilities.
Gi`dXip 18;EG>CI3 8kki`Ylk\j Table 62.1 presents the attributes of 18;EG>CI3 that apply to all printers. KXYc\ -)%(
Attributes of the 18;EG>CI3 Tag
ATTRIBUTE
DESCRIPTION
hdjgXZ
Absolute or relative pathname to a PDF file or a PDF document variable
Viig^WjiZHigjXi
ColdFusion structure that contains attribute key-value pairs
Xdadg
nZh or cd (defaults to cd)
Xde^Zh
Number of copies (defaults to &)
ÄYZa^in
nZh or cd (defaults to cd)
eV\Zh
Page or pages to print (defaults to Vaa)
eVeZg
Options are aZiiZg, aZ\Va, 6), 6*, 7), 7*, 7)"?>H, 7*"?>H, and any media supported by the printer
eVhhldgY
PDF source file owner or user password
eg^ciZg
String that specifies the printer name
ineZ
E9;
Even though most of these options are generic and obvious, there are still some aspects of printerspecific behavior to notice. For instance, the default settings for some of the attributes listed in Table 62.1 may be printer dependent, and if you may try (mistakenly) to use attributes or values that are inappropriate, the available ÄYZa^in attribute can assist in protecting against such mistakes, as discussed in the next section.
Gi`ek\i$;\g\e[\ek 8kki`Ylk\j Your printer may support many more attributes than those listed in Table 62.1: options to control two-sided printing, stapling, reversal of the page order, and much more. These special attributes can be discovered using the \ZiEg^ciZg>c[d function. Note, though, that you can’t use these printer-dependent attributes on the 18;EG>CI3 tag. Instead, you must specify them by way of the Viig^WjiZHigjXi attribute (and only by way of this attribute), as will be discussed later.
CI3 explains the purpose of many of these other attributes and their values. Note that the some of the results of \Zieg^ciZg^c[d show different values even for attributes listed in Table 62.1 (such as for eVeZg, which shows that the printer supports a (m* value, which was not listed previously). We can also see in the dump a YZ[Vjaih structure nested within the result, and it shows defaults for both those attributes in Table 62.1 and the additional attributes unique to this printer.
GXjj`e^ Gi`ek\i$;\g\e[\ek 8kki`Ylk\j n`k_ 6iig^WjiZHigjXi Now that we have the available attributes for the capabilities of this printer, we can pass them to the 18;EG>CI3 tag, but we can’t simply list them as attributes of the tag, as we can those in Table 62.1. Instead, these nonstandard attributes must be passed in using the special Viig^WjiZHigjXi attribute. The following example will help demonstrate this concept. If you want to print the first 16 pages of a document as two-sided on your printer, you can use the following: 1X[hZi VHZi2ph^YZh2ºild"h^YZY"adc\"ZY\Zº!eV\Zh2º&"&+ºr3 1X[eg^ci hdjgXZ2ºhdbZWdd`#eY[º Viig^WjiZHigjXi2ºVHZiº3
359
360
CHAPTER
62
Server-Side Printing
Notice that we’re creating a structure, called VHZi (using ColdFusion’s ability to create structures implicitly rather than with HigjXiCZl). In it, we’re placing two keys: the attributes h^YZh and eV\Zh set to the desired values. EFK
CI3 Xe[ Viig^WjiZHigjXi# `e n_`Z_ ZXj\ k_\ Xkki`Ylk\j ]fi k_\ kX^ fm\ii`[\ k_fj\ `e k_\ jkilZkli\%
K_\ ÄYZa^in 8kki`Ylk\ ColdFusion provides the flexibility to create and use attributes that may or may not be supported by a given printer, but this flexibility can also require management. Among the attributes listed in Table 62.1 is one whose purpose may not be self-evident: ÄYZa^in. This attribute indicates whether the attribute values specified must match exactly what the printer supports. For instance, although 7) is listed as a value for eVeZg in Table 62.1, it’s not listed as a valid value in the output the dump of the sample printer’s supported eVeZg values shown in Figure 62.1. If you specify ÄYZa^in2ºnZhº, the print attempt will fail with a traditional ColdFusion error: :ggdg DXXjggZY L]^aZ EgdXZhh^c\ GZfjZhi >ckVa^Y bZY^V dg eVeZg [dg i]Z X[eg^ci iV\# :ggdg/ BZY^V ^hd"W) ^h cdi kVa^Y dc 7gdi]Zg B;8"-+)%9 Eg^ciZg# 6kV^aVWaZ bZY^V VgZ ^hd"V)!cV"aZiiZg!cV"aZ\Va!ZmZXji^kZ!^hd"V*!^hd"V+!^hd"W*!^hd"W+!cV"cjbWZg" &%"ZckZadeZ!^hd"YZh^\cViZY"adc\!^hd"X*!bdcVgX]"ZckZadeZ!Dg\Vc^oZg ?!Dg\Vc^oZg @!^ckd^XZ!6) Adc\!( m *![da^d!JhZg 9ZÄcZY!^hd"V(!iVWad^Y!_^h"W)!6jidbVi^X";ZZYZg!ide!BE IgVn!bVcjVa
If you specify ÄYZa^in2ºcdº, however, the printer will make a reasonable attempt to print the job using the provided settings. The ÄYZa^in attribute is optional and defaults to cd.
AXmX Gi`ek J\im`Z\j Xe[ 8kki`Ylk\j Besides being dependent on the printer, the particular printer attributes supported also depend on the operating system and network printer server, if there is one, as well as Java Print Service (JPS), on which the 18;EG>CI3 tag is based. Many printers support attributes that are not accessible from JPS. For example, according to the ColdFusion documentation, “the JPS for a Macintosh OS X running JDK 1.5 supports the fewest printer attributes. Upgrading to JDK 1.6 adds some functionality, but finishing attributes are still not supported.”
8[[`k`feXc 18;EG>CI3 8kki`Ylk\j In addition to the list of tag attributes in Table 62.1 and any printer-specific attributes obtained via the \Zieg^ciZg^c[d function, a subset of the attributes for 18;EG>CI3 listed in the CFML Reference work even when ÄYZa^in2ºnZhº, though they’re not listed in the \Zieg^ciZg^c[d result. These include: VjidGdiViZ6cY8ZciZg, eV\ZHXVa^c\, gZkZghZEV\Zh, and jhZE9;EV\ZH^oZ. See the CFML Reference for more details on the uses and values for these attributes.
Determining Available Printers
;\k\id`e`e^ 8mX`cXYc\ Gi`ek\ij The section “Printing to the Default Printer” discussed how to determine and print to the default printer for your system, and the section “Printing to Another Printer” showed you how to print to another printer, whether on the computer running ColdFusion or on another server on your network. How do you determine what other printers are available?
;\k\id`e`e^ 8mX`cXYc\ Gi`ek\ij Of course, you can use your operating system–provided mechanisms to list available printers. If your application server runs on Windows, for instance, you can generally use Start > Printers and Faxes. But you can also obtain the list of printers from the ColdFusion Administrator’s Server Settings > Settings Summary page, as shown in Figure 62.2. This figure also highlights the portion of the report showing the printers defined on this server. =`^li\ -)%) Available printers shown on the ColdFusion Administrator Settings Summary page.
Note that this list shows only the printers’ names, not their capabilities. For that, you must pass the printer name to the \ZiEg^ciZg>c[d function, like this: 1X[Yjbe kVg2º\Zieg^ciZg^c[d¹=E AVhZg?Zi ''%% HZg^Zh E8A +ºº3
This will result in a dump of a structure as shown in Figure 62.1. K@G
Pfl ZXe Xcjf fYkX`e k_\ c`jk f] XmX`cXYc\ gi`ek\ij gif^iXddXk`ZXccp% :fc[=lj`fe [f\j efk Zlii\ekcp gifm`[\ X Yl`ck$`e ]leZk`fe ]fi k_`j gligfj\# Ylk 9\e =fikX _Xj ni`kk\e X e`]kp Zljkfd kX^ k_Xk ZXe gifm`[\ k_\ `e]fidXk`fe% @k i\c`\j fe Xe le[fZld\ek\[ XdaY[jh^dc#eg^ci#Eg^ciZg>c[d ZcXjj `e AXmX% 8j cfe^ Xj pfl _Xm\eËk [`jXYc\[ jlZ_ `ek\ieXc AXmX fYa\Zkj `e k_\ :fc[$ =lj`fe 8[d`e`jkiXkfi# pfl ZXe lj\ k_`j Zljkfd kX^# n_`Z_ pfl ZXe fYkX`e Xk ]iie/$$lll#XÅ^W#dg\$jY[#X[b4^Y2&,-'%
361
362
CHAPTER
62
Server-Side Printing
N_Xk 8Yflk Fk_\i Gi`ek\ij6 If you want to print to a printer that’s not listed on the System Information page, you must add the printer using your operating system mechanism for adding printers. ColdFusion offers no means to do this independently. As mentioned previously, however, if the printer is available on another printer on your network, you can print to that printer by forming a UNC path to name the server and printer, as shown in the section “Printing to Another Printer” earlier in this chapter.
Gi`ek\i G\id`jj`fej Because ColdFusion relies on the operating system to control the available printers, it is also subject to security permissions that may be defined for the printers. Even if a printer is configured locally on the system, the printer will not be available if the account under which ColdFusion is running does not have the proper permissions. By default, ColdFusion installs and runs as the Local System account (or “nobody” on Linux and Unix), which may not have printer access rights. For information on running ColdFusion as a specific user, see the following tech note: ]iie/$$`W'#VYdWZ#Xdb$Xeh$&,'$icT&,',.#]iba.
I\cXk\[ =\Xkli\j Before concluding coverage of 18;EG>CI3, there are a few additional topics worth noting.
Gi`ek Cf^ Whenever you print a document using 18;EG>CI3, ColdFusion logs the action (and some types of failures) to a eg^ci#ad\ file that appears in the standard 1XdaY[jh^dc 3$ad\h directory. You can also view the logs using the ColdFusion Administrator, on the Log Files page, in the Debugging and Logging section. For each printed file, two lines will be created, tracking the date, time, application name, and thread ID as well as details such as the following: ¹Eg^ci _dW »hdbZWdd`#eY[¼ hiVgiZY# Eg^ciZg »7gdi]Zg B;8"-+)%9 Eg^ciZg¼#º ¹Eg^ci _dW »hdbZWdd`#eY[¼ lVh hZci id eg^ciZg# Eg^ciZg/ »7gdi]Zg B;8"-+)%9 Eg^ciZg¼# IdiVa eV\Zh/ '#º
This log information can be very helpful when you’re trying to diagnose printing problems or confirm successful printing.
Lj`e^ 18;I=G:693 Because the process of sending a print job to a printer (or more typically, to your operating system’s print spooling service) may take some time, you can configure your code so that you don’t need to wait for the completion of that process of sending the job to the printer. This is a great use for the ColdFusion tag 18;I=G:693.
Related Features
You can run a print job asynchronously (meaning without waiting for completion of its transmission to the printer or spool) by enclosing the 18;EG>CI3 tag within a 18;I=G:693 tag block, as the following example shows: 1X[i]gZVY cVbZ2ºeg^ciº3 1X[eg^ci hdjgXZ2ºhdbZÄaZ#eY[º eg^ciZg2ºQQh&%%&egc%'QCIC"'L"=ET7L%'º3 1$X[i]gZVY3
¨ J\\ :_Xgk\i )-# ÈDXeX^`e^ K_i\X[j#É `e 8[fY\ :fc[=lj`fe 0 N\Y 8ggc`ZXk`fe :fejkilZk`fe B`k# Mfcld\ )1 8ggc`ZXk`fe ;\m\cfg d\ek# ]fi dfi\ [\kX`cj fe 18;I=G:693%
Gi`ek`e^ Fk_\i k_Xe G;=j As has been made clear from the beginning of this chapter, the 18;EG>CI3 tag can be used only to print PDF files. That may seem a severe limitation, and you may rightfully say, “What if I have some HTML or other content that I want to print?” Remember that ColdFusion offers the 18;9D8JB:CI3 tag, which enables you to create a PDF file from HTML that you dynamically create using CFML. And even if you don’t have an existing PDF file that you need to print, recall that various tags in ColdFusion can create PDF files that you may want to print, including the results of ColdFusion Report Builder (with 18;G:EDGI3), 18;E9;3, 18;E9;;DGB3, and more. See Chapter 28, “Working with PDF Files,” in Volume 2 for more information.
363
This page intentionally left blank
:?8GK;N, BD9>;N9C , or 9:A:I:. If none is specified, the default is FJ:GN.
C6B:
Required if 68I>DC2ºFjZgnº. This represents the name of the query object returned from the 18;A96E3 query.
H:GK:G
Required. The address hosting the LDAP server. Entries may be in the form of the server’s IP address (that is, 127.0.0.1) or its DNS entry (that is, aYVe# hZgkZg#Xdb).
EDGI
Optional. The port to which LDAP is configured for listening. The default is 389.
JH:GC6B:
Required if hZXjgZ attribute is set to 8;HHAT76H>8.
E6HHLDG9
Optional. The password used in conjunction with the JH:GC6B: attribute for authentication.
I>B:DJI
Optional. the time, in seconds, allowed for the LDAP operation before timeout occurs. If none is provided, the default is 60 seconds.
Using
KXYc\ -*%)
(continued)
NAME
DESCRIPTION
B6MGDLH
Optional. Used only with 68I>DC2ºFjZgnº, this specifies the number of records to return from the LDAP query, similar to the 18;FJ:GN3 tag. Note that this attribute does not work with all LDAP servers.
HI6GI
Required (and only used) if 68I>DC2ºFjZgnº. This represents the DN starting point from which to begin the search within the Directory Information Tree (DIT).
H8DE:
Optional. Defines the scope for searching the DIT, starting at the value specified in the HI6GI attribute. Possible values are 7VhZ, DcZAZkZa, or HjWIgZZ.
6IIG>7JI:H
Required for FJ:GN, 699, BD9>;N, and BD9>;N9C actions. When used with FJ:GN, it represents a comma-delimited list of return values used as columns in a query output; an asterisk () returns all values. For 699 and BD9>;N, it represents a semicolon-separated list of add/modify values. For BD9>;N9C , it represents the new DN for the entry and does not check for correct syntax.
;>AI:G
Optional. Used with 68I>DC2ºFjZgnº to provide the search criteria for the query. The default filter is dW_ZXi8aVhh2, which returns all values.
HDGI
Optional. A comma-delimited list of attributes and sort directions by which to sort a query, as in HDGI2ºXc 6H8! bV^a 9:H8º.
HDGI8DCIGDA
Optional. A comma-delimited list of sort control options for a query. Possible values are VhX, YZhX, and cdXVhZ. Sorting, by default, is case-sensitive in ascending order (VhX). The YZhX value sorts the query in descending order, and cdXVhZ discards case-sensitivity. Values can be used in tandem, as in HDGI8DCIGDA2ºcdXVhZ! YZhXº.
9C
Required for 9:A:I:, 699, BD9>;N, and BD9>;N9C actions. Represents the DN for the entry being operated on.
HI6GIGDL
Optional. Used only with 68I>DC2ºFjZgnº, this specifies the starting row for returning records. The default is 1.
BD9>;NINE:
Optional. Used only with 68I>DC2ºBdY^[nº, this specifies the way to handle modifications within the attribute list. Possible values are VYY, gZeaVXZ, and YZaZiZ. Default value is ¹GZeaVXZº.
G:7>C9
Optional. Boolean value indicating whether 18;A96E3 should rebind the referral callback and reissue the query via the referred address using the original credentials. Default value is ¹cdº.
G:;:GG6A
Optional. Specifies the number of hops allowed in a referral. A zero value indicates 18;A96E3’s capability to use referred addresses is disabled, and no data is returned.
H:8JG:
Optional. Identifies the type of security to use, such as 8;HHAT76H>8 or 8;HHAT8A>:CIT6JI= , and additional information that is required by the corresponding security type. Possible field values are XZgi^ÄXViZTYW, XZgi^ÄXViZTcVbZ, `ZnTYW, and `ZnldgYTYW.
H:E6G6IDG
Optional. The character used to separate values in multivalue attributes. The default is a comma (!).
9:A>B>I:G
Optional. The character used to separate cVbZ2kVajZ pairs. The default is a semicolon (0).
G:IJGC6H7>C6GN
Optional. A comma- (or space) separated list of columns that are returned as a binary values.
369
370
CHAPTER
63
Interacting with Directory Services
EFK
DC2ºFJ:GNº C6B:2º\ZiHijYZcihº 6IIG>7JI:H2ºdj!Xc!bV^aº HI6GI2ºX2jhº H8DE:2ºHJ7IG::º ;>AI:G2ºdj2I^hX] HX]dda d[ i]Z 6gihº3 18;H8G>EI3 hi6iih 2 HigjXiCZl0 hi6iih#hZgkZg 2 ¹aYVe#cnj#ZYjº0 hi6iih#VXi^dc2ºFJ:GNº0 hi6iih#Viig^WjiZh2ºdj!Xc!bV^aº0 hi6iih#cVbZ2º\ZiHijYZcih7n6iigº0 hi6iih#hiVgi2ºX2jhº0 hi6iih#hXdeZ2ºHJ7IG::º0 hi6iih#ÄaiZg2ºdj2I^hX] HX]dda d[ i]Z 6gihº0 1$8;H8G>EI3 18;A96E 6G<JB:CIH8DAA:8I>DC2ºhi6iihº$3
Because some of 18;A96E3’s attributes are a bit involved, the next few sections discuss in more depth how these attributes work.
K_\ 68I>DC 8kki`Ylk\ ColdFusion’s 18;A96E3 tag supports five distinct actions: N
FJ:GN
N
699
N
BD9>;N
N
BD9>;N9C
N
9:A:I:
is the default. The FJ:GN action allows you to return a query object (record set) from an LDAP server. This can be used in the same way as any query object, such as one returned from the 18;FJ:GN3 tag. Three variables, in addition to the query results, are available to the returned query object: FJ:GN
N
GZXdgY8djci.
The number of records returned from the query object.
N
8dajbcA^hi.
N
8jggZciGdl. The current row index of the query being processed by an output mechanism, such as 18;DJIEJI3 or 18;ADDE3.
A comma-delimited list of column names in the query.
Using
When 68I>DC is set to FJ:GN, you are also required to use the C6B:, 6IIG>7JI:H, and HI6GI parameters. So at its simplest, your call to 18;A96E3 would look like this: 18;A96E 68I>DC2ºFJ:GNº C6B:2ºcVbZ d[ fjZgnº H:GK:G2ºhZgkZg adXVi^dcº 6IIG>7JI:H2ºViig^WjiZ a^hiº HI6GI2ºhiVgi^c\ adXVi^dc [dg i]Z fjZgnº3
The 699 action is used to add entries to your LDAP server. This action requires the 9C and 6IIG>7JI:H parameters. In this context, the DN is used to specify where to place the added entry in the DIT and should contain the full DN sequence. The 6IIG>7JI:H parameter is used to specify the cVbZ2kVajZ pairs to be added at the location specified in the 9C parameter. Each cVbZ2kVajZ pair should be delimited with a semicolon (0), unless otherwise specified in the 9:A>B>I:G parameter. The most basic form of an 699 action is as follows: 18;A96E 68I>DC2º699º H:GK:G2ºhZgkZg adXVi^dcº 6IIG>7JI:H2ºcVbZ2kVajZ0 cVbZ'2kVajZ'0 cVbZc2kVajZcº 9C2ºi]Z Y^hi^c\j^h]ZY cVbZ id VYYº3
The BD9>;N action allows you to modify attribute values for LDAP entries, one or more at a time. The only attribute that cannot be modified through this action is the DN, which is modified through the BD9>;N9C action. As with the 699 action, the BD9>;N action’s attributes are sent to the 6IIG>7JI:H parameter in semicolon-separated cVbZ2kVajZ pairs. The following is the BD9>;N action’s basic required format: 18;A96E 68I>DC2ºBD9>;Nº H:GK:G2ºhZgkZg adXVi^dcº 6IIG>7JI:H2ºcVbZ2kVajZ0 cVbZ'2kVajZ'0 cVbZc2kVajZcº 9C2ºi]Z Y^hi^c\j^h]ZY cVbZ d[ i]Z Zcign id WZ bdY^ÄZYº3
The BD9>;N9C attribute performs one specific function: It changes the DN for an entry. To change the DN, you must supply the original DN as well as the new DN replacement: 18;A96E 68I>DC2ºBD9>;N9Cº H:GK:G2ºhZgkZg adXVi^dcº 6IIG>7JI:H2ºi]Z cZl gZeaVXZbZci 9C kVajZº 9C2ºi]Z dg^\^cVa 9C kVajZ WZ^c\ bdY^ÄZYº3
EFK
;N9C Xkki`Ylk\ f] 18;A96E3 [f\j efk Z_\Zb k_\ ;E ]fi jpekXo \iifij# Xe[ Xj X i\jlck# pfli \ekip dXp Y\Zfd\ dXc]fid\[%
The only requirement for deleting an entry is the entry’s DN. Having this value allows 18;A96E3 to locate the entity you want to delete. After you delete an entry, it is gone, and because of this, you should make sure that the DN value is correct.
371
372
CHAPTER
63
Interacting with Directory Services
To delete an entry, use the following syntax: 18;A96E 68I>DC2º9:A:I:º H:GK:G2ºhZgkZg adXVi^dcº 9C2ºi]Z 9C gZegZhZci^c\ i]Z Zcign id YZaZiZº3
K_\ H8DE: 8kki`Ylk\ When querying an LDAP server, 18;A96E3 provides a means to narrow that search—in addition to filtering—with three types of “branch” scopes. Each of these scopes dictates how the search is performed relative to the value entered in the HI6GI attribute. In other words, the HI6GI attribute is used as a starting point for the search, and the H8DE: value tells 18;A96E3 where to search from that starting point. These scopes are as follows: If 76H: is chosen, 18;A96E3 only searches the current branch specified in the HI6GI attribute. Any branches above or below this branch are not searched.
N
76H:#
N
DC:A:K:A# To search a single level below the branch specified in the HI6GI attribute, use the DC:A:K:A value. This only searches one level below the starting branch. Any branches above or more than one level below this branch are not searched.
N
HJ7IG::#
This is the most commonly used value because it searches the entry specified in the HI6GI attribute as well as all branches beneath it. HjWIgZZ will not, however, search branches above the starting value. If you need to search branches higher up in the directory tree, simplify your starting value by making it more generalized.
Because of the recursive nature of the HjWIgZZ scope, performance may suffer with larger directory structures. As a result, you may want to use a drill-down approach when traversing a large directory, using the DC:A:K:A scope in succession.
K_\ BD9>;NINE: 8kki`Ylk\ When modifying an LDAP entry using 68I>DC2ºBdY^[nº, the BD9>;NINE: attribute allows you to specify which type of modification to perform. Having this capability allows you greater flexibility and control for modifying complex entries. The following list provides detailed descriptions for each BD9>;NINE: and the action(s) it performs: N
699# To add an attribute value to a multivalue entry, you can use the 699 modify type. The attribute(s) to be added should be listed in the 6IIG>7JI:H parameter as a semicolon-separated list, unless a different separator is specified in the H:E6G6IDG parameter.
N
9:A:I:#
N
G:EA68:# As the default modify type, the G:EA68: value overwrites the existing attribute(s) specified in the 6IIG>7JI:H parameter.
To delete a specific attribute from a multivalue entry, use the 9:A:I: modify type. The value listed in the 6IIG>7JI:H parameter represents the value to delete if it exists.
Interacting with Directories
EFK
;N XZk`fe% 8[[`k`feXccp# \eki`\j k_Xk ZfekX`e CJAA mXcl\j ZXeefk Y\ df[`Ô\[%
K_\ H:8JG: 8kki`Ylk\ The H:8JG: attribute identifies which type of security to use in your LDAP calls. ColdFusion currently supports the 8;HHAT76H>8 only. The format for 8;HHAT76H>8 authentication takes two values: H:8JG:2¹8;HHAT76H>8!8:GI>;>86I:T97º
When using H:8JG:, keep the following in mind: N
The 8:GI>;>86I:T97 value is the name or path to a valid (Netscape cert7.db format) certificate database file. This value is the default and need not be explicitly specified.
N
The 8:GI>;>86I:TC6B: represents the client certificate to send to the server.
N
The @:NT97 value is the name or path to a valid (Netscape key3.db format) file that contains the public or private key pair for the certificate.
N
The @:NLDG9T97 holds the password to the key database (@:NT97).
N
If no path information is given for the 8:GI>;>86I:T97 or @:NT97 values, ColdFusion looks for them in the default LDAP directory.
@ek\iXZk`e^ n`k_ ;`i\Zkfi`\j For the examples in this chapter, most LDAP servers will support the conventions used. You may, however, run into situations where certain attributes or object classes do not work, depending on the LDAP software you’re using. To understand more about the specific structure of your platform, check the documentation included with it.
8Zk`m\ ;`i\Zkfip Active Directory is an essential component of each version of Windows network architecture since Windows 2000. It behaves as a directory service to allow organizations to centrally manage information on users (including security information), as well as other network resources. Windows Domain Controllers each have an Active Directory service available, which provides access to the directory database. Using a standard CFLDAP tag, developers can integrate with this Active Directory to enable users to log into ColdFusion applications using their Windows network username and password. Listing 63.1 shows a simple example to authenticate users against Active Directory.
373
374
CHAPTER
C`jk`e^ -*%(
63
Interacting with Directory Services
aYVe6ji]#X[b —Authenticating
a User with 18;A96E3
18;ADC3 18;>; CDI ^h9ZÄcZY¹;dgb#jhZgcVbZº3 18;>C8AJ9: I:BEA6I:2ºad\^c$ad\^cT[dgb#X[bº3 18;67DGI3 18;:AH:3 18;IGN3 18;A96E VXi^dc2ºFJ:GNº C6B:2ºVji]º 6IIG>7JI:H2ºXcº HI6GI2ºXc2jhZgh!YX2iViVb!YX2cZiº H:GK:G2ºadXVa]dhiº EDGI2º(-.º JH:GC6B:2º[dgb#jhZgcVbZº E6HHLDG92º[dgb#eVhhldgYº3 18;H:I ^h6ji]Zci^XViZY2ºnZhº3 18;86I8= ineZ2º6CNº3 18;H:I ^h6ji]Zci^XViZY2ºcdº3 1$8;86I8=3 1$8;IGN3 18;>; kVg^VWaZh#^h6ji]Zci^XViZY3 18;ADCJH:G C6B:2º;dgb#jhZgcVbZº E6HHLDG92º;dgb#eVhhldgYº GDA:H2º6ji]Zci^XViZY JhZgº3 18;:AH:3 18;>C8AJ9: I:BEA6I:2ºad\^c$ad\^cT[dgb#X[bº3 1](3Ndjg ^c[dgbVi^dc ^h cdi kVa^Y# EaZVhZ ign V\V^c#1$](3 18;67DGI3 1$8;>;3 1$8;>;3 1$8;ADC3
In Listing 63.1, an LDAP query is run against a Microsoft Active Directory (AD) and is wrapped with a 18;ADC3 tag. By specifying the username and password as provided by the end user’s form input, this query will run successfully only if those fields match a valid user’s username and password from the Active Directory. If either the username or password is incorrect, the Active Directory will throw an error message. By wrapping the call with a 18;IGN3 tag, we are able to catch the error message. The end result is that we have set a variable called ^h6ji]Zci^XViZY to either true if the query is able to run, or false if not. After the end of the 18;IGN3 block, we check the value of ^h6ji]Zci^XViZY. If it is true, the user is logged in; otherwise, the user is redirected to the login form.
Hl\ip`e^ ;`i\Zkfi`\j One of the first things you need to know about any action within 18;A96E3 that requires authentication is how to use the JH:GC6B: and E6HHLDG9 attributes. The first common mistake is to enter the username by itself, as odd as that may sound. Often the full DN is required for the entry that represents the user and the username: JH:GC6B:2ºXc2biViVb!Xc2GZX^e^Zcih!dj2DLH!d2DgVc\Z L]^e HijY^dhº
Interacting with Directories
Most of the time, however, you can just use the Xc as the username, like this: JH:GC6B:2ºXc2biViVbº
So in this example, the username is actually biViVb, but the JH:GC6B: attribute requires the Xc2 (common name) prefix. The E6HHLDG9 attribute, on the other hand, does not require any special considerations, so you simply enter it as it’s written: E6HHLDG92ºbiViVbT&'(º
EFK
DC2ºFJ:GNº C6B:2º7JI:H2ºº HI6GI2ºº ;>AI:G2ºj^Y2º3 1""" 9^heaVn Vaa cVbZ$kVajZ eV^gh [dg ZVX] j^Y """3 18;DJIEJI FJ:GN2º9I=2º&%%º 7DG9:G2º&º 8:AAHE68>C; 8jggZciGdl :F &3 1IG3 1I=3CVbZ1$I=3 1I=3KVajZ1$I=3 1$IG3 1$8;>;3 1IG3 1I93cVbZ1$I93 1I93kVajZ1$I93 1$IG3 1$I67A:3 1$8;DJIEJI3
EFK
7JI:H value, you’re telling 18;A96E3 to return all attributes for all entries returned from the ;>AI:G scope value. In this example, you used the j^Y2 filter to signify that you want all entries () that have a j^Y returned. The dW_ZXi8aVhh is now dg\Vc^oVi^dcVaEZghdc! eZghdc! Ide
and one of the DNs is Xc2biViVb! Xc2GZX^e^Zcih! dj2DLH! d2DgVc\Z L]^e HijY^dh
Having this list of available attributes allows you to build your 699 action construct. In Listing 63.3, you’ll add “Ben Forta,” along with his corresponding personal information values, to the Orange Whip Studios (DLH) organizational unit (dj) within the company. C`jk`e^ -*%*
6YY:cign#X[b —Adding
and Testing an Entry
1""" JhZ i]Z »699¼ VXi^dc id XgZViZ V cZl Zcign """3 18;A96E 68I>DC2º699º H:GK:G2ºadXVa]dhiº JH:GC6B:2ºXc2biViVbº E6HHLDG92ºbiViVbT&'(º 6IIG>7JI:H2ºdW_ZXiXaVhh2dg\Vc^oVi^dcVaEZghdc! eZghdc! Ide0 Xc27Zc ;dgiV0 hc2;dgiV0 bV^a27ZcT;dgiV5dgVc\Z"l]^e"hijY^dh#Xdb0 dj2DLHº 9C2ºXc2WZcT[dgiV! Xc2GZX^e^Zcih! dj2DLH! d2DgVc\Z L]^e HijY^dhº3 1""" FjZgn id ZchjgZ i]Z Zcign lVh VYYZY """3 18;A96E 68I>DC2ºFJ:GNº C6B:2º7JI:H2ºYc!Xc!iZaZe]dcZcjbWZgº HI6GI2ºº ;>AI:G2ºj^Y2biViVbº3 1I67A: L>9I=2º&%%º 7DG9:G2º&º 8:AAHE68>CDC attribute set to BD9>;N. The first query returned a DN of Xc2biViVb! Xc2GZX^e^Zcih! dj2DLH! d2DgVc\Z L]^e HijY^dh
which is what you’ll use to modify the listing. For this next example, you’ll change the telephone number value. The first call to 18;A96E3, as shown previously in Listing 63.3, gathers the DN. This value is required for any modifications you want to make. The second call uses the first call’s DN as the value you supply to the DN attribute. Finally, one more 18;A96E3 call is used to requery the server, returning the newly modified results that contain the iZaZe]dcZCjbWZg value. See Listing 63.5 to get a better idea of how this works. C`jk`e^ -*%,
BdY^[nIZaZe]dcZ#X[b —Modifying
an Entry
1""" JeYViZ i]Z »iZaZe]dcZCjbWZg¼ kVajZ """3 1""" I]Z 9C kVajZ ^h jhZY [gdb V egZk^djh 8;A96E XVaa """3 18;A96E 68I>DC2ºBD9>;Nº H:GK:G2ºadXVa]dhiº JH:GC6B:2ºXc2biViVbº E6HHLDG92ºbiViVbT&'(º 6IIG>7JI:H2ºiZaZe]dcZcjbWZg2.&. *** " ****º 9C2ºDC2ºFJ:GNº C6B:2º7JI:H2ºhi2C80 higZZi2&'( DgVc\Z L]^e AVcZº BD9>;NINE:2º699º 9C2ºXc2biViVb!Xc2GZX^e^Zcih!dj2DLH!d2DgVc\Z L]^e HijY^dhº3 1""" Gjc V fjZgn id \Vi]Zg i]Z cZl gZhjaih """3 18;A96E 68I>DC2ºFJ:GNº C6B:2º7JI:H2ºjc^fjZbZbWZgº HI6GI2ºXc2BVg`Zi^c\!Xc2GZX^e^Zcih!dj2DLH!d2DgVc\Z L]^e HijY^dhº3 1""" >[ i]Z \gdje YdZhc¼i Zm^hi! i]gdl Vc Zggdg bZhhV\Z VcY VWdgi """3 18;>; CDI 7JI:H2ºYcº HI6GI2ºº ;>AI:G2ºj^Y2JhZgº3 1""" 8gZViZ V hZb^Xdadc"hZeVgViZY a^hi d[ jhZg 9C¼h """3 1""" :VX] 9C cZZYh id ]VkZ ^ih XdbbVh ZhXVeZY l^i] Vcdi]Zg XdbbV """3 18;H:I BZbWZgh2 BZbWZgh ¹!º GZeaVXZDC2ºBD9>;Nº H:GK:G2ºadXVa]dhiº JH:GC6B:2ºXc2biViVbº E6HHLDG92ºbiViVbT&'(º 6IIG>7JI:H2ºdW_ZXiXaVhh2\gdjeD[Jc^fjZCVbZh0jc^fjZbZbWZg2BZbWZghº 9C2ºXc2BVg`Zi^c\!Xc2GZX^e^Zcih!dj2DLH!d2DgVc\Z L]^e HijY^dhº3
While this is a tedious process, there is a far easier approach to making these modifications, with the use of the BdY^[nIneZ attribute. The final code for these sections can be found encapsulated in the A96E#X[X file shown in Listing 63.9 later in this chapter.
Df[`]p`e^ <eki`\j n`k_ BD9>;NINE: To help you appreciate the benefits of using the BD9>;NINE: attribute, the previous section demonstrated how cumbersome it can be to modify entries manually. Luckily, there is an easier way, by using the BD9>;NINE: attribute of the 18;A96E3 tag.
383
384
CHAPTER
63
Interacting with Directory Services
To recap, reread the section “The BD9>;NINE: Attribute” earlier in this chapter. The VYY modify type will look like the following: 18;A96E 68I>DC2ºBD9>;Nº BD9>;NINE:2º699º H:GK:G2ºadXVa]dhiº JH:GC6B:2ºXc2biViVbº E6HHLDG92º_biViVbT&'(º 6IIG>7JI:H2ºXc2_d]cTYdZ!Xc2GZX^e^Zcih!dj2DLH!d2DgVc\Z L]^e HijY^dhº 9C2ºXc2BVg`Zi^c\!Xc2GZX^e^Zcih!dj2DLH!d2DgVc\Z L]^e HijY^dhº3
Had you added two users, you would separate each DN with a comma. To replace entries, use the gZeaVXZ modify type. :8LK@FE
9\ ZXi\]lc k_Xk pfl [f efk fm\ini`k\ \o`jk`e^ \eki`\j n`k_ X j`e^c\ \ekip% K_\ \eki`\j pfl jlggcp kf k_\ 6IIG>7JI:H gXiXd\k\i n`cc i\gcXZ\ Xcc \o`jk`e^ \eki`\j ]fi k_\ ;E jg\Z`Ô\[%
For this example, you’ll replace the current marketing users with a list of the old users plus a new user, John Doe. For this example, all the new users are placed in a variable called BZbWZgh. Following is what the new users list will look like: Xc2biViVb!Xc2GZX^e^Zcih!dj2DLH!d2DgVc\Z L]^e HijY^dh! Xc2WZcT[dgiV!Xc2GZX^e^Zcih!dj2DLH!d2DgVc\Z L]^e HijY^dh! Xc2_d]cTYdZ!Xc2GZX^e^Zcih!dj2DLH!d2DgVc\Z L]^e HijY^dh
To replace the old members with the new, use the gZeaVXZ modify type: 18;A96E 68I>DC2ºBD9>;Nº BD9>;NINE:2ºG:EA68:º H:GK:G2ºadXVa]dhiº JH:GC6B:2ºXc2biViVbº E6HHLDG92ºbiViVbT&'(º 6IIG>7JI:H2ºBZbWZghº 9C2ºXc2BVg`Zi^c\!Xc2GZX^e^Zcih!dj2DLH!d2DgVc\Z L]^e HijY^dhº3
To delete an entry, use the YZaZiZ modify type. This next example would delete the John Doe user from the Marketing group: 18;A96E 68I>DC2ºBD9>;Nº BD9>;NINE:2º9:A:I:º H:GK:G2ºadXVa]dhiº JH:GC6B:2ºXc2biViVbº E6HHLDG92ºbiViVbT&'(º 6IIG>7JI:H2ºXc2_d]cTYdZ!Xc2GZX^e^Zcih!dj2DLH!d2DgVc\Z L]^e HijY^dhº 9C2ºXc2BVg`Zi^c\!Xc2GZX^e^Zcih!dj2DLH!d2DgVc\Z L]^e HijY^dhº3
Df[`]p`e^ X ;`jk`e^l`j_\[ EXd\ Modifying a DN requires 18;A96E3’s BD9>;N9C action. You cannot modify a DN using the BD9>;N action.
Interacting with Directories
There are two values of interest when modifying a DN: the original DN and the replacement DN. The original DN is placed in the DN attribute, whereas the new replacement DN is placed in the 6IIG>7JI:H parameter as follows: 18;A96E 68I>DC2ºBD9>;N9Cº H:GK:G2ºadXVa]dhiº JH:GC6B:2ºXc2biViVbº E6HHLDG92ºbiViVbT&'(º 6IIG>7JI:H2ºXc2_VcZTYdZ!Xc2GZX^e^Zcih!dj2DLH!d2DgVc\Z L]^e HijY^dhº 9C2ºXc2_d]cTYdZ!Xc2GZX^e^Zcih!dj2DLH!d2DgVc\Z L]^e HijY^dhº3
;\c\k`e^ <eki`\j Deleting an entry is possibly the easiest action to perform using 18;A96E3. Because of this, it is worth pointing out that after an entry is deleted, it’s gone for good, and there isn’t an “undo” mechanism. The following code snippet shows the process of removing an entry from LDAP. The only requirements for doing so are having sufficient access as well as the DN of the entry you want to delete. 18;A96E 68I>DC2º9:A:I:º H:GK:G2ºadXVa]dhiº JH:GC6B:2ºXc2biViVbº E6HHLDG92ºbiViVbT&'(º 9C2ºXc2biViVb!Xc2GZX^e^Zcih!dj2DLH!d2DgVc\Z L]^e HijY^dhº3
After the code is run, the entry is gone. As a safeguard, you may want to create a database to hold “deleted” entries in the event that you need to restore an accidentally deleted entry. Using this concept, you would query the entry to gather all its Name/Value pairs, run an insert query, and then, if all goes well, run the LDAP deletion. Listing 63.7 shows how to build a simple mailing list that enables you to send a message to every member in your LDAP directory. This example could be modified to filter specific groups or organizational units, or to enable you to specify filter options. The choices are unlimited. C`jk`e^ -*%.
A96EBV^aA^hi#X[b —Using
LDAP to Create a Mailing List
1""" EgdXZhh XdYZ ^[ i]Z [dgb lVh hjWb^iiZY """3 18;>; >h9ZÄcZY¹;DGB#HjWb^iº3 1""" H^beaZ [dgb kVa^YVi^dc [dg ZVX] ÄZaY """3 18;>; CDI AZc;DGB#BZhhV\ZI^iaZ3 18;I=GDL B:HH6;3 18;>; CDI AZc;DGB#BZhhV\Z3 18;I=GDL B:HH6;3 1""" Gjc i]Z A96E fjZgn """3 18;A96E 68I>DC2ºFJ:GNº C6B:2ºA96EBV^aA^hiº H:GK:G2ºadXVa]dhiº JH:GC6B:2ºXc2biViVbº E6HHLDG92ºbiViVbT&'(º H8DE:2ºHJ7IG::º
385
386
CHAPTER
63
C`jk`e^ -*%.
Interacting with Directory Services
(continued)
6IIG>7JI:H2ºXc!bV^aº HI6GI2ºº3 1""" >[ gZXdgYh VgZ gZijgcZY! gjc 8;B6>A """3 18;>; A96EBV^aA^hi#GZXdgY8djci3 18;B6>A ;GDB2ºa^hi"hZgkZ5dgVc\Z"l]^e"hijY^dh#Xdbº ID2ºbV^aº HJ7?:8I2º;dgb#BZhhV\ZI^iaZº H:GK:G2ºbV^a#dgVc\Z"l]^e"hijY^dh#Xdbº FJ:GN2ºA96EBV^aA^hiº3 =Zaad! Xc ;DGB#BZhhV\Z 1$8;B6>A3 1""" ;ZZYWVX`! hZci """3 173Ndjg bZhhV\Z lVh hjXXZhh[jaan hZci#1$731E3 18;:AH:3 1""" ;ZZYWVX`! [V^aZY """3 173Cd gZXdgYh Zm^hi ^c i]Z Y^gZXidgn#1$73 1$8;>;3 1$8;>;3 1""" ;dgb jhZY id ZciZg i]Z bV^a^c\ a^hi XdciZcih """3 1;DGB 68I>DC2ºA96EBV^aA^hi#X[bº B:I=D92ºedhiº3 :ciZg V i^iaZ [dg i]Z bV^a^c\/17G3 1>CEJI C6B:2ºBZhhV\ZI^iaZº B6MA:CcWdmº gZXjghZ2ºigjZº hZgkZg2ºhZhh^dc#hZgkZgº jhZgcVbZ2ºH:HH>DC#bV^aJhZgº eVhhldgY2ºH:HH>DC#bV^aEVhhlYº $3 1X[Yjbe kVg2ºbn;daYZghº3
EFK
cWdm$6gX]^kZh).
;DA9:GH>O:
Size of the folder specified in bytes.
ColdFusion Exchange Server Tags
1X[ZmX]Vc\ZXVaZcYVg3 Use 1X[ZmX]Vc\ZXVaZcYVg3 to create, delete, get, and modify Exchange calendar events and retrieve or delete event attachments. A persistent or transient connection is required for this tag. Table 64.4 lists the 1X[ZmX]Vc\ZXVaZcYVg3 attributes. KXYc\ -+%+ 1X[ZmX]Vc\ZXVaZcYVg3 Attributes ATTRIBUTE
ACTION
REQUIRED DESCRIPTION
VXi^dc
N/A
Yes
One of the following actions to perform: XgZViZ: Create an appointment
or meeting event, including allday events. YZaZiZ: Delete one or more
events. YZaZiZ6iiVX]bZcih: Delete an
event attachment. \Zi: Retrieve one or more events using a filters specified with 1X[ZmX]Vc\ZÄaiZg3. \Zi6iiVX]bZcih: Retrieve
attachments for a specific event. bdY^[n: Modify an existing
event. gZhedcY: Respond to an event. ViiVX]bZciEVi]
\Zi6iiVX]bZcih
No
The path to the directory in which ColdFusion will save attachments. If omitted, ColdFusion does not save any attachments. If using a relative path, the ColdFusion iZbe directory, as returned by \ZiIZbe9^gZXidgn, is the path root.
XdccZXi^dc
All
No
The name of the Exchange Server connection specified in 1X[ZmX]Vc\ZXdccZXi^dc3. If omitted, you must create a connection by specifying the required 1X[ZmX]Vc\ZXdccZXi^dc3
attributes in this tag. ZkZci
XgZViZ
bdY^[n
Yes
A structure containing the event properties to set or modify, and their values. Surround the attribute value in hash marks (#).
395
396
CHAPTER
KXYc\ -+%+
64
Integrating with Microsoft Exchange
(continued)
ATTRIBUTE
ACTION
REQUIRED DESCRIPTION
\ZcZgViZJc^fjZ;^aZcVbZh \Zi6iiVX]bZcih
No
A Boolean value (default: cd) specifying whether to automatically generate unique file names for multiple attachments with the same file name. If nZh is specified, ColdFusion appends an incrementing number to the file name (before the extension) of conflicting attachments.
bZhhV\Z
No
Optional message to send in the deletion or response notification.
Yes
A ColdFusion query variable name that contains the retrieved events or information about the attachments that were retrieved.
gZhedcY
No
Boolean value specifying whether to notify others of event changes.
gZhedcY
Yes
Must be one of the following:
YZaZiZ gZhedcY
cVbZ
\Zi \Zi6iiVX]bZcih
cdi^[n
gZhedchZIneZ
YZaZiZ
VXXZei YZXa^cZ iZciVi^kZ gZhjai
XgZViZ
No
A variable name for the UID of the created event. Use this UID value in the j^Y attribute to specify that event for further actions other than XgZViZ.
j^Y
YZaZiZ
Yes
Case-sensitive Exchange UID value(s) that uniquely identifies event(s) on which actions are performed.
YZaZiZ6iiVX]bZcih \Zi6iiVX]bZcih bdY^[n gZhedcY
Only the YZaZiZ action accepts a comma-delimited list of UID values; all other actions accept only a single UID value.
The XgZViZ action creates calendar events. Use the ZkZci attribute to provide a structure that defines the calendar event: for example, attendees, duration, and reminders. Table 64.5 lists possible event items. Specify the gZhjai attribute to retrieve the UID of the created event. The following code creates a recurring birthday appointment:
ColdFusion Exchange Server Tags
1X[hXg^ei3 hi:kZci#6aa9Vn:kZci 2 igjZ0 hi:kZci#^hGZXjgg^c\ 2 igjZ0 hi:kZci#GZXjggZcXZIneZ 2 ¹N:6GANº0 hi:kZci#HjW_ZXi 2 ;DGB#cVbZº¼h 7^gi]YVnº0 hi:kZci#HiVgiI^bZ 2 XgZViZ9ViZ'%%,! &! .0 1$X[hXg^ei3 1X[ZmX]Vc\ZXVaZcYVg VXi^dc2ºXgZViZº ZkZci2ºhi:kZciº gZhjai2ºXVaZcYVg>9º hZgkZg2ºhZhh^dc#hZgkZgº jhZgcVbZ2ºH:HH>DC#bV^aJhZgº eVhhldgY2ºH:HH>DC#bV^aEVhhlYº $3 1X[Yjbe kVg2ºXVaZcYVg>9º $3
K@G
Kf Zi\Xk\ Xe Xggf`ekd\ek# lj\ k_\ XgZViZ XZk`fe n`k_flk jg\Z`]p`e^ k_\ GZfj^gZY6iiZcYZZh fi Dei^dcVa 6iiZcYZZh Xkki`Ylk\%
KXYc\ -+%,
Calendar Event Properties
PROPERTY
DEFAULT
REQUIRED
DESCRIPTION
6aa9Vn:kZci
[VahZ
No, if :cYI^bZ is specified.
A Boolean value indicating whether this is an all-day event.
6iiVX]bZcih
No
One or more absolute paths to the files to send as attachments. Separate file paths with semicolons (;) on Windows, and colons (:) for Unix and Linux. Attachments are added to preexisting attachments when the bdY^[n action is used, and existing attachments are not deleted.
9jgVi^dc
No
The duration of the event in minutes.
:cYI^bZ
No, if 6aa9Vn:kZci The end time of the event, in any valid is true ColdFusion date-time format.
>bedgiVcXZ
cdgbVa
No
One of the following values: ]^\], cdgbVa, adl.
>hGZXjgg^c\
No
A Boolean value indicating whether this event repeats. If true, you must specify a GZXjggZcXZIneZ element and elements to specify the recurrence details. Table 64.6 lists the recurrence fields.
AdXVi^dc
No
A string that specifies the event location.
BZhhV\Z
No
A string containing a message describing the event. The string can include HTML formatting.
Dei^dcVa 6iiZcYZZh
No
A comma-delimited list of mail IDs.
Dg\Vc^oZg
No
A string that specifies the event organizer’s name.
GZb^cYZg
No
The time (in minutes) before the event, to display a reminder message.
397
398
CHAPTER
KXYc\ -+%,
64
Integrating with Microsoft Exchange
(continued)
PROPERTY
DEFAULT
REQUIRED
DESCRIPTION
GZfj^gZY 6iiZcYZZh
No
A comma-delimited list of mail IDs.
GZhdjgXZh
No
A comma-delimited list of mail IDs for Exchange scheduling resources, such as conference rooms and display equipment.
HZch^i^k^in
No
One of the following values: cdgbVa, XdbeVcn"XdcÄYZci^Va, eZghdcVa, eg^kViZ.
HiVgiI^bZ
Yes
The start time of the event, in any valid ColdFusion date-time format. If you specify a date and time in this attribute and specify a N:6GAN GZXjggZcXZIneZ value with no other recurrence attributes, the event recurs yearly at the day and time specified in this attribute.
HjW_ZXi
KXYc\ -+%-
No
A string that describes the event subject.
Calendar Recurrence Types
ELEMENT
TYPE
DEFAULT
DESCRIPTION
GZXjggZcXZIneZ
All
96>AN
Used only if the >hGZXjgg^c\ attribute is true. Must be one of the following values: 96>AN, L::@AN, BDCI=AN, N:6GAN.
igjZ
A Boolean value; if true, the event recurs until changed or deleted. Mutually exclusive with GZXjggZcXZ8djci and GZXjggZcXZ:cY9ViZ.
GZXjggZcXZCd:cY9ViZ All
GZXjggZcXZ8djci
All
The number of times the event recurs. Mutually exclusive with GZXjggZcXZ:cY9ViZ and GZXjggZcXZCd:cY9ViZ.
GZXjggZcXZ:cY9ViZ
All
The date of the last recurrence. Mutually exclusive with GZXjggZcXZ8djci and GZXjggZcXZCd:cY9ViZ.
GZXjggZcXZ;gZfjZcXn 96>AN, L::@AN, & BDCI=AN
The frequency of the recurrence in days, weeks, or months, depending on the type. For example, for 96>AN recurrence, a GZXjggZcXZ;gZfjZcXn value of ( schedules the event every three days.
GZXjg:kZgnLZZ`9Vn
The recurrence of the event on every weekday, but not on Saturday or Sunday. Mutually exclusive with GZXjggZcXZ;gZfjZcXn.
96>AN
ColdFusion Exchange Server Tags
KXYc\ -+%-
(continued)
ELEMENT
TYPE
GZXjggZcXZ9Vnh
L::@AN
DEFAULT
DESCRIPTION
The day or days of the week on which the event occurs. Must be one or more of the following values in a comma-delimited list: BDC , IJ:, L:9, I=J, ;G>, H6I, HJC . If you omit this field for a weekly recurrence, the event recurs on the day of the week that corresponds to the specified start date.
GZXjggZcXZ9Vn
BDCI=AN, N:6GAN
The day of the week on which the event occurs. Must be one of the following values: BDC , IJ:, L:9, I=J, ;G>, H6I, HJC .
GZXjggZcXZLZZ`
BDCI=AN, N:6GAN
The week of the month or year on which the event recurs. Valid values are Äghi, hZXdcY, i]^gY, [djgi], aVhi.
GZXjggZcXZBdci]
N:6GAN
The month of the year on which the event recurs. Valid values are ?6C , ;:7, B6G, 6EG, B6N, ?JC , ?JA , 6J< , H:E, D8I, CDK, 9:8.
The YZaZiZ action removes existing events from the server. You must specify one or more event UIDs in a comma-delimited list. ColdFusion will ignore any invalid UIDs and delete only events specified with valid ones. It will throw an error if all the UIDs are invalid. The YZaZiZ6iiVX]bZcih action removes the specified existing attachment from the event on the server. You must specify a single event UID; multiple UIDs are not allowed. The \Zi action retrieves information about existing events. Use the cVbZ attribute to create a variable to contain the returned query. Use the 1X[ZmX]Vc\ZÄaiZg3 child tag to specify the event to retrieve. K@G
Lj\ k_\ \Zi XZk`fe kf i\ki`\m\ k_\ L@; f] \m\ekj k_Xk pfl nXek kf XZZ\jj n`k_ k_\ YZaZiZ# YZaZiZ6iiVX]bZcih# \Zi6iig^WjiZh# bdY^[n# Xe[ gZhedchZ XZk`fej%
The \Zi6iiVX]bZcih action retrieves information about an existing event’s attachments. You must specify a single event UID; multiple UIDs are not allowed. Use the cVbZ attribute to create a variable to contain the returned query. EFK
Account Information page (where <enterprise application definition> is the name of your application, such as Bn8daY;jh^dc.6ee) will load in your browser. The form will display a text box for each of the fields on your ColdFusion 9 application login form that you entered on the Create Enterprise Application
Accessing ColdFusion 9 from SharePoint
Definition page. Enter the appropriate values for SharePoint to provide to your ColdFusion 9 application. When you have entered all the information, click the OK button. 8. If you designated your enterprise application definition as having an Individual account type, you can repeat steps 4 though 7 for as many Windows users as you would like. However, if you designated your enterprise application definition as having a Group account type, you can have only a single Windows group associated with the enterprise application definition, so if you repeat steps 4 through 7 for a different group, the credentials you entered for the first group will be deleted.
K_\ :=JJFN\YGXik N\Y GXik The CFSSOWebPart Web Part is a customized version of the Page Viewer Web Part that enables you to pass SSO credentials to a ColdFusion 9 application. The CFSSOWebPart Web Part passes SharePoint SSO credentials to the ColdFusion 9 application; the ColdFusion 9 application’s access control logic is responsible for authenticating the credentials. The CFSSOWebPart Web Part is a part of the ColdFusion 9 SharePoint Integration Webparts Zip file that is available to be downloaded from ]iie/$$lll#VYdWZ#Xdb$hjeedgi$XdaY[jh^dc$YdlcadVYh#]iba.
DXb`e^ k_\ :=JJFN\YGXik N\Y GXik 8mX`cXYc\ kf J_Xi\Gf`ek After you have downloaded the CFSSOWebPart Web Part, you must make the CFSSOWebPart Web Part available to SharePoint. The following steps guide you through this process: 1. Download the ColdFusion 9 SharePoint Integration Webparts Zip file from ]iie/$$lll# VYdWZ#Xdb$hjeedgi$XdaY[jh^dc$YdlcadVYh#]iba and extract the 8;.HHDLZWEVgi#lhe ÄaZ. 2. Use SharePoint’s Stsadm tool to add the CFSSOWebPart Web Part to SharePoint. This can be accomplished with the following command: hihVYb "d VYYhdaji^dc "[ 8;.HHDLZWEVgi#lhe
You may need to change the command-line directory to the directory in which hihVYb#ZmZ is located. In addition, you must either move the 8;.HHDLZWEVgi#lhe file to the directory from which you run the command or alter the reference to the 8;.HHDLZWEVgi#lhe file in the command arguments to include the path to that file. For more information on the Stsadm tool, see ]iie/$$iZX]cZi#b^Xgdhd[i#Xdb$Zc"jh$ a^WgVgn$XX'+&.*+d[ÄXZ#&'#Vhem. 3. Use Stsadm to deploy the CFSSOWebPart Web Part to SharePoint. This can be accomplished with the following command: hihVYb "d YZeadnhdaji^dc "cVbZ 8;.HHDLZWEVgi#lhe "VaaXdciZcijgah "adXVa "Vaadl>H# """3 1X[hZi KVg^VWaZh#ad\^cHigjXi#jhZgCVbZ 2 ¹º3 1X[hZi KVg^VWaZh#ad\^cHigjXi#eVhhldgY 2 ¹º3 1"""8gZViZ i]Z eVgVbZiZgh higjXijgZ id eVhh id i]Z LZW hZgk^XZ#"""3 1X[hZi KVg^VWaZh#eVgVbhHigjXi 2 pdW_ZXiCVbZ2º8VaZcYVgº! dW_ZXiIneZ2ºA^hiºr3
437
438
CHAPTER
65
C`jk`e^ -,%)
Integrating with SharePoint and Portals
(continued)
1""" >ckd`Z i]Z C; directory is in the ColdFusion 9 Web root on multiserver and J2EE installations; on server installations, the L:7">C; directory is in the ColdFusion 9 built-in Web server’s Web root). Similarly, to deploy a CFC that extends 8daY;jh^dcEdgiaZi#X[X as a local portlet, you must define the portlet in the edgiaZi#mba file located in the L:7">C; directory of your ColdFusion 9 Enterprise multiserver or J2EE installation. In either case, you should find that the file already exists and has sample content that is inactive by virtue of being commented out, but if need be, you can simply create the file and the content. In both the X["lhge"edgiaZi#mba file and the edgiaZi#mba file, you define each portlet in the body of its own 1edgiaZi3 tag. You can create a single definition file that, with one important change, can be used as either your X["lhge"edgiaZi#mba file or your edgiaZi#mba file. This process works so well because both files conform to the Portlet 1.0 deployment descriptor format, and in those cases in which one file has slightly different requirements from the other, ColdFusion simply ignores information it doesn’t need—so the only issue is the one instance in which the same element needs a different value in the respective files. Listing 65.5 shows a sample of what this file could look like for deploying the CFCs from Listing 65.3 and Listing 65.4. C`jk`e^ -,%,
a^hi^c\+*T*#mba—ColdFusion
9 Portlet Definition File
14mba kZgh^dc2º%º ZcXdY^c\2ºJI;"-º43 1edgiaZi"Vee mbach2º]iie/$$_VkV#hjc#Xdb$mba$ch$edgiaZi$edgiaZi"VeeT&T%#mhYº mbach/mh^2º]iie/$$lll#l(#dg\$'%%&$MBAHX]ZbV"^chiVcXZº mh^/hX]ZbVAdXVi^dc2º]iie/$$_VkV#hjc#Xdb$mba$ch$edgiaZi$edgiaZi"VeeT&T%#mhY ]iie/$$ _VkV#hjc#Xdb$mba$ch$edgiaZi$edgiaZi"VeeT&T%#mhYº kZgh^dc2º%º3 1edgiaZi3 1edgiaZi"cVbZ3Cdi]^c\EdgiaZi1$edgiaZi"cVbZ3 1Y^heaVn"cVbZ mba/aVc\2ºZcº3Cdi]^c\ EdgiaZi1$Y^heaVn"cVbZ3 1YZhXg^ei^dc mba/aVc\2ºZcº3I]^h ^h V Cdi]^c\ EdgiaZi#1$YZhXg^ei^dc3 1edgiaZi"XaVhh3XdaY[jh^dc#edgiaZi#8daY;jh^dcEdgiaZi1$edgiaZi"XaVhh3 1^c^i"eVgVb3 1cVbZ3X[XCVbZ1$cVbZ3 1kVajZ3edgiaZih#a^hi^c\+*T(1$kVajZ3 1$^c^i"eVgVb3 1hjeedgiZY"adXVaZ3Zc1$hjeedgiZY"adXVaZ3
441
442
CHAPTER
65
C`jk`e^ -,%,
Integrating with SharePoint and Portals
(continued)
1hjeedgih3 1b^bZ"ineZ3iZmi$]iba1$b^bZ"ineZ3 1edgiaZi"bdYZ3K>:L1$edgiaZi"bdYZ3 1$hjeedgih3 1edgiaZi"^c[d3 1i^iaZ36 Cdi]^c\ EdgiaZi1$i^iaZ3 1$edgiaZi"^c[d3 1$edgiaZi3 1edgiaZi3 1edgiaZi"cVbZ3=ZaadLdgaYEdgiaZi1$edgiaZi"cVbZ3 1Y^heaVn"cVbZ mba/aVc\2ºZcº3=Zaad LdgaY EdgiaZi1$Y^heaVn"cVbZ3 1YZhXg^ei^dc mba/aVc\2ºZcº3I]^h ^h V =Zaad LdgaY EdgiaZi#1$YZhXg^ei^dc3 1edgiaZi"XaVhh3XdaY[jh^dc#edgiaZi#8daY;jh^dcEdgiaZi1$edgiaZi"XaVhh3 1^c^i"eVgVb3 1cVbZ3X[XCVbZ1$cVbZ3 1kVajZ3edgiaZih#a^hi^c\+*T)1$kVajZ3 1$^c^i"eVgVb3 1hjeedgiZY"adXVaZ3Zc1$hjeedgiZY"adXVaZ3 1hjeedgih3 1b^bZ"ineZ3iZmi$]iba1$b^bZ"ineZ3 1edgiaZi"bdYZ3K>:L1$edgiaZi"bdYZ3 1$hjeedgih3 1edgiaZi"^c[d3 1i^iaZ36 =Zaad LdgaY EdgiaZi1$i^iaZ3 1$edgiaZi"^c[d3 1$edgiaZi3 1$edgiaZi"Vee3
You can see that the file has several elements for naming and describing each portlet. In addition, notice that for each portlet there are two elements for mapping that portlet to the CFC that implements that portlet’s functionality: the <edgiaZi"XaVhh3 element and the 1kVajZ3 element of the 1^c^i"eVgVb3 element. In the edgiaZi#mba file, the value of the <edgiaZi"XaVhh3 element needs always to be XdaY[jh^dc#edgiaZi#8daY;jh^dcEdgiaZi, and the actual CFC that implements the portlet’s functionality needs to be specified in the 1kVajZ3 element of the 1^c^i"eVgVb3 element. By contrast, in the X["lhge"edgiaZi#mba file, the value of the 1kVajZ3 element of the 1^c^i"eVgVb3 element is unimportant: you need only specify the CFC that implements the portlet’s functionality as the value of the <edgiaZi"XaVhh3 element. Accordingly, Listing 65.5 is a edgiaZi#mba file that can easily be changed so that it can be used as a X["lhge"edgiaZi#mba file.
Lj`e^ X I\dfk\ :fc[=lj`fe 0 Gfikc\k n`k_ X GfikXc J\im\i When you have both created the CFC to implement a portlet’s functionality and defined the portlet in the X["lhge"edgiaZi#mba descriptor file, you have a ColdFusion 9 portlet you can use as a WSRP Producer to interact with any WSRP Consumer on any platform—including, as mentioned earlier, SharePoint. The specifics of configuring your portal server to interact with your remote ColdFusion 9 portlet are beyond the scope of this book, but because the ColdFusion 9 portlet appears from the perspective of your portal server just like any other WSRP Producer, you can simply follow the documentation for configuring your portal server to interact with a WSRP Producer.
Accessing Portal Servers from ColdFusion 9
Lj`e^ X CfZXc :fc[=lj`fe 0 <ek\igi`j\ Gfikc\k n`k_ X AXmX GfikXc J\im\i When you have both created the CFC to implement a portlet’s functionality and defined the portlet in the edgiaZi#mba descriptor file, you have a ColdFusion 9 Enterprise portlet you can use to supply data and content to portal pages on local Java portal servers. The specifics of configuring your Java portal server to interact with your local ColdFusion 9 portlet are beyond the scope of this book, but because the ColdFusion 9 Enterprise portlet appears from the perspective of your Java portal server just like any other local portlet, you can simply follow the documentation for configuring your portal server to interact with a portlet.
Fk_\i 8ggifXZ_\j ]fi 8ZZ\jj`e^ :fc[=lj`fe 0 ]ifd GfikXc J\im\ij In addition to supplying data and content to your portal server via ColdFusion 9 portlets, there may be additional ways to access ColdFusion data and content from your portal server. Although portal servers vary in what features they have, many portal servers have features you can use in conjunction with ColdFusion 9 features to access ColdFusion 9 data and content. The following are the most notable of these: N
Links: Portal servers generally offer many different ways you can include simple links to ColdFusion 9 application URLs.
N
Email: Often, portal servers can be configured to receive email. If your portal server can receive email, you can use the ColdFusion 9 1X[bV^a3 tag (see Chapter 20) to email ColdFusion data to your portal server.
N
RSS: Some portal servers provide native capabilities for reading RSS feeds, and those portal servers that do not provide native capabilities for reading RSS feeds may allow you to deploy custom-developed portlets which do read RSS feeds. You can then use the ColdFusion 9 1X[[ZZY3 tag (see Chapter 60) to produce an RSS feed you consume from your portal server.
8ZZ\jj`e^ GfikXc J\im\ij ]ifd :fc[=lj`fe 0 Different portal servers may expose data in different ways. Portal servers may expose standard Web services much in the same way SharePoint does; however, there are no widely implemented standards or specifications for this. If your portal server does expose data via Web services, you can, of course, consume those Web services with ColdFusion (see Chapter 59). Similarly, if your portal server can send email messages, you can use the 1X[ede3 tag (see Chapter 20), the 1XÄbVe3 tag (see Chapter 20), and the 1X[ZmX]Vc\ZbV^a3 tag (see Chapter 64) in your ColdFusion 9 applications to retrieve data sent in those email messages. If your portal server can publish RSS feeds, you can use the 1X[[ZZY3 tag (see Chapter 60) in your ColdFusion 9 applications to consume those feeds.
443
444
CHAPTER
65
Integrating with SharePoint and Portals
Regardless of whether or not your portal server exposes data in other ways, almost all portal servers have a concept like portal pages that ultimately are simply Web pages. With such portal servers, you can use the following approaches for accessing portal server data and content in ColdFusion 9 applications: N
Links: Portal servers generally expose URLs for each portal page. Therefore, you can include links to such URLs in your ColdFusion 9 applications.
N
Application content: You can use the 1X[]iie3 tag (see Chapter 58) in your ColdFusion 9 applications to access portal page content made available via URLs.
:?8GKci('PR
^ciPR
adc\ $ HnhiZb#>ci+)
adc\
adc\PR $ HnhiZb#>ci+)PR
adc\PR
hWniZ $ HnhiZb#HWniZ
WniZ
hWniZ PR$ HnhiZb#HWniZPR
WniZPR
h]dgi $ HnhiZb#>ci&+
h]dgi
h]dgiPR $ HnhiZb#>ci&+PR
h]dgiPR
HnhiZb#9ZX^bVa
W^\YZX^bVa
HnhiZb#Hig^c\
Hig^c\
EFK
ci&+
HnhiZb#7dmZYJH]dgi
j^ci $ HnhiZb#J>ci('
HnhiZb#7dmZYJ>ci
jadc\ $ HnhiZb#J>ci+)
HnhiZb#7dmZYJAdc\
:fc[=lj`fe Xe[ %Ec^i^Va^oZ8dbedcZci p r $$$ 1hjbbVgn3 $$$ 8aZVc je Vcn gZhdjgXZh WZ^c\ jhZY# $$$ 1$hjbbVgn3 egdiZXiZY dkZgg^YZ kd^Y 9^hedhZ Wdda Y^hedh^c\ p ^[Y^hedh^c\ XdbedcZcih 2 cjaa p XdbedcZcih#9^hedhZ0 r WVhZ#9^hedhZY^hedh^c\0 r ZcYgZ\^dc $$ =Zaad LdgaY ZmVbeaZ lZW hZgk^XZ PLZWBZi]dYR ejWa^X hig^c\ =ZaadLdgaY p gZijgc ¹=Zaad LdgaYº0 r r r
.NET Web Service: Returning a Simple Type
To compile the code in Visual Studio .NET, go to Build and select the proper build scenario. To build out all objects in the solution, select Build Solution or press Ctrl+Shift+B. Compile errors will be displayed in the output window. The message “Build: 1 succeeded, 0 failed, 0 skipped” means you’re ready to go and test your Web service. To do this, go to Debug and select Start. Internet Explorer will launch and display the LZWHZgk^XZ& class definition. The documentation provided through the .NET interface gives you the ability to test the =ZaadLdgaY method. Click it, and you’ll see the test page. Click Invoke, and a browser window is displayed showing the XML generated by the operation. Figure 66.4 shows the screens and the expected results. =`^li\ --%+ WebService1 class definition and test page with result.
Notice that the default test scenario used here is exercised by an HTTP EDHI. This can prove problematic for applications that utilize an HTTP c^i^Va^oZ8dbedcZci p r $$$ 1hjbbVgn3 $$$ 8aZVc je Vcn gZhdjgXZh WZ^c\ jhZY# $$$ 1$hjbbVgn3 egdiZXiZY dkZgg^YZ kd^Y 9^hedhZ Wdda Y^hedh^c\ p ^[Y^hedh^c\ XdbedcZcih 2 cjaa p XdbedcZcih#9^hedhZ0 r WVhZ#9^hedhZY^hedh^c\0 r ZcYgZ\^dc $$ I]Z :I>IA:! E>I8=I:MI! G6I>C9! HJBB6GN [gdb Äabh 1$8;FJ:GN3 18;H:I ^ci6YYEVgV\gVe]8djcig 2 6ggVnAZcMBA9dX#9dXjbZci#WdYn#e3 18;ADDE FJ:GN2ºfgn;^abGVi^c\hº 3 18;H:I ^ci6YYEVgV\gVe]8djcig 2 ^ci6YYEVgV\gVe]8djcig &3 18;H:I iZbe 2 6ggVn>chZgi6iMBA9dX#9dXjbZci#WdYn#MBA8]^aYgZc! ^ci6YYEVgV\gVe]8djcig! MBA:aZbCZlMBA9dX! ¹l/eº3 1""" VYY V cZl eVgV\gVe] VcY V cZl gdl id i]Z ^chZgiZY eVgV\gVe] """"3 18;H:I iZbe 2 6ggVn6eeZcYMBA9dX#9dXjbZci#WdYn#eP^ci6YYEVgV\gVe]8djcigR# MBA8]^aYgZc! MBA:aZbCZlMBA9dX! ¹l/gº3 18;H:I iZbe 2 6ggVn6eeZcYMBA9dX#9dXjbZci#WdYn#eP^ci6YYEVgV\gVe]8djcigR#g#MBA8]^aY gZc! MBA:aZbCZlMBA9dX! ¹l/iº3 18;H:I MBA9dX#9dXjbZci#WdYn#eP^ci6YYEVgV\gVe]8djcigR#g#i#MBAIZmi 2 ¹BDK>:I>IA:" E>I8=I:MI G6I>C9º3 1$8;ADDE3 18;H:I higCZlMBA 2 idHig^c\MBA9dX 3 18;;>A: 68I>DC 2 ¹lg^iZº ;>A:2º6eea^XVi^dc#LdgY#hig7aVc`IZbeaViZ9^gQldgYQYdXjbZci#mbaº DJIEJI2ºhigCZlMBAº3 18;O>E ;>A:2º6eea^XVi^dc#LdgY#higDjieji9^gQXgZViZYdXmTJJ>9IZbe#YdXmº HIDG:E6I=2ºnZhº G:8JGH:2ºigjZº DK:GLG>I:2ºnZhº HDJG8:2º6eea^XVi^dc#LdgY#hig7aVc`IZbeaViZ9^gº $3 18;9JBE kVg2ºhigCZlMBAº3
You should be able to now open and start to use the new XgZViZYdXmTMMMM#YdXm file in Word 2007. Be careful; if you edit an OOXML document, it will add your edits in a different element. 1l/e l/gh^YG2º%%;9''(+º l/gh^YG9Z[Vjai2º%%;9''(+º l/gh^YE2º%%;9''(+º3 1l/g3 1l/i mba/heVXZ2ºegZhZgkZº36YYgZhh1$l/i3 1$l/g3 1$l/e3
Word OOXML Containers
The following XML is produced when the capital A was changed (revised) to a lowercase a: 1l/e l/gh^YG2º%%;9''(+º l/gh^YG9Z[Vjai2º%%;9''(+º l/gh^YE2º%%;9''(+º3 1l/g l/gh^YG2º%%&+%)'6º3 1l/i3V1$l/i3 1$l/g3 1l/g3 1l/i mba/heVXZ2ºegZhZgkZº3YYgZhh1$l/i3 1$l/g3 1$l/e3
Here,
gh^YG
is a revision identifier. It is a unique ID generated when an edit is made.
M`\n`e^ X Nfi[ FFODC =`c\ Because of the revision identifier, the text can start to get lost within the SML. To view the raw text content of the YdXjbZci#mba file (without having document tracking, for instance), we can use the MBAHZVgX] function (Listing 67.4). C`jk`e^ -.%+
K^Zl9D8#X[b —Viewing
the Raw Text of a Word 2007 Document
1"""" ;^aZ cVbZ/ K^Zl9D8#X[b EjgedhZ/ K^Zl V LdgY '%%, 9D8 ÄaZ 6ji]dg/ BVii IViVb """"3 18;O>E 68I>DC2ºGZVYº ;>A:2º6eea^XVi^dc#LdgY#higDjieji9^gQXgZViZYdXmT%-&6&.%;"(;;&");7%" **+.,(6,-6,;8:;-#YdXmº :CIGNE6I=2ºldgYQYdXjbZci#mbaº K6G>67A:2ºhigMBAiZmiº3 18;H:I MBA9dX2MBAEVghZ¹higMBAiZmiº3 18;H:I mbaEVgV\gVe]:aZbZcih 2 MbaHZVgX]MBA9dX! ¹$$PadXVa"cVbZ2¼YdXjbZci¼R$PadXVa" cVbZ2¼WdYn¼R$PadXVa"cVbZ2¼e¼Rº3 18;H:I mbaEVgV\gVe]:aZbZcih 2 mbaEVgV\gVe]:aZbZcih 3 18;ADDE ;GDB2º&º ID2º6ggVnAZcmbaEVgV\gVe]:aZbZcihº >C9:M2º^ciEVgV8djcigº3 18;H:I mbaGdl:aZbZcih 2 MbaHZVgX]MBAEVghZmbaEVgV\gVe]:aZbZcihP^ciEVgV8djcigR! ¹$$PadXVa"cVbZ2¼e¼R$PadXVa"cVbZ2¼g¼R$PadXVa"cVbZ2¼i¼Rº3 18;ADDE ;GDB2º&º ID2º6ggVnAZcmbaGdl:aZbZcihº >C9:M2º^ciGdl8djcigº3 18;DJIEJI3mbaGdl:aZbZcihP^ciGdl8djcigR#MBAIZmi1$8;DJIEJI3 1$8;ADDE3 17G3 1$8;ADDE3
:i\Xk`e^ X ;peXd`Z Nfi[ FFODC ;fZld\ek You may be familiar with mail merging. In this example, we will create our own mail merge (dynamic) document by using a standard Word OOXML document. These are the basic steps: N
Open a document template.
N
Assign the part of the document to be dynamically populated,
N
Save the document.
475
476
CHAPTER
67
Integrating with Microsoft Office
EFK
E.
N
Read ldgYQYdXjbZci#mba.
N
Replace dynamic content with values.
N
Close, store, view, and deliver the document.
Changing the purchaser is simple. All we need to do is replace the characters with dynamic variables (Listing 67.5). C`jk`e^ -.%,
9ncVb^X9D8#X[b —Replacing eaVXZ]daYZgh
with Dynamic Content
1"""" ;^aZ cVbZ/ 9ncVb^X9D8#X[b EjgedhZ/ GZeaVXZ i]Z eaVXZ]daYZgh l^i] YncVb^X XdciZci [gdb V fjZgn# 6ji]dg/ BVii IViVb """"3
Word OOXML Containers
C`jk`e^ -.%,
(continued)
18;H:I ^ciXdciVXi>9 2 (3 18;O>E 68I>DC2ºjco^eº ;>A:2º6eea^XVi^dc#LdgY#higGddi9^gQ;^ab7jY\Zih#YdXmº 9:HI>C6I>DC2º6eea^XVi^dc#LdgY#higIZbe9^gQÄabWjY\Ziº dkZglg^iZ2ºnZhº 3 18;;>A: 68I>DC 2 ¹gZVYº ;>A:2º6eea^XVi^dc#LdgY#higIZbe9^gQÄabWjY\ZiQldgYQYdXjbZci#mbaº K6G>67A:2ºhigMBAIZmiº3 18;FJ:GN 96I6HDJG8: 2 ¹DLHº C6B:2ºfgn8dciVXihº3 HZaZXi [gdb XdciVXih l]ZgZ XdciVXi>9 2 ^ciXdciVXi>9 1$8;FJ:GN3 18;FJ:GN 96I6HDJG8: 2 ¹DLHº C6B:2ºfgn;^abhº3 HZaZXi BDK>:I>IA:! E>I8=I:MI! HJBB6GN! 6BDJCI7J9C9 [gdb Äabh 1$8;FJ:GN3 18;DJIEJI FJ:GN2ºfgn8dciVXihº 3 18;H:I higMBAIZmi2gZeaVXZCd8VhZhigMBAIZmi!º;^ghiCVbZº!º;^ghiCVbZº!º6aaº3 18;H:I higMBAIZmi2gZeaVXZCd8VhZhigMBAIZmi!ºAVhiCVbZº!ºAVhiCVbZº!º6aaº3 18;H:I higMBAIZmi2gZeaVXZCd8VhZhigMBAIZmi!º6YYgZhhº!º6YYgZhhº!º6aaº3 18;H:I higMBAIZmi2gZeaVXZCd8VhZhigMBAIZmi!ºX^inº!ºX^inº!º6aaº3 18;H:I higMBAIZmi2gZeaVXZCd8VhZhigMBAIZmi!ºo^eº!ºo^eº!º6aaº3 18;H:I higMBAIZmi2gZeaVXZCd8VhZhigMBAIZmi!ºXdjcignº!ºXdjcignº!º6aaº3 1$8;DJIEJI3 18;;>A: 68I>DC 2 ¹lg^iZº ;>A:2º6eea^XVi^dc#LdgY#higIZbe9^gQÄabWjY\ZiQldgYQYdXjbZci#mbaº DJIEJI2ºidHig^c\MBA9dXº3 18;O>E 68I>DC2ºo^eº HIDG:E6I=2ºnZhº ;>A:2º6eea^XVi^dc#LdgY#higDjieji9^gQ;>ABWJ9chZgi6iMBA9dX#9dXjbZci#WdYn#iWa#MBA8]^aYgZc! >CI' ^ci8Zaa8djcig! MBAEVgi 3 18;H:I MBA9dX#9dXjbZci#WdYn#iWa#igP^ci8Zaa8djcigR#iXP&R#eP&R#gP&R#iP&R#MBAIZmi ¹BDK>:I>IA:º 3 18;H:I MBA9dX#9dXjbZci#WdYn#iWa#igP^ci8Zaa8djcigR#iXP'R#eP&R#gP&R#iP&R#MBAIZmi ¹E>I8=I:MIº 3 18;H:I MBA9dX#9dXjbZci#WdYn#iWa#igP^ci8Zaa8djcigR#iXP(R#eP&R#gP&R#iP&R#MBAIZmi ¹HJBB6GNº3 18;H:I MBA9dX#9dXjbZci#WdYn#iWa#igP^ci8Zaa8djcigR#iXP)R#eP&R#gP&R#iP&R#MBAIZmi ZcXn;dgbVi6BDJCI7J9C9º3 1$8;DJIEJI3 18;H:I ^ci8Zaa8djcig 2 ^ci8Zaa8djcig &3 18;H:I MBA9dX#9dXjbZci#WdYn#iWa#igP^ci8Zaa8djcigR#iXP)R#eP&R#gP&R#iP&R#MBAIZmi 2 AHXjggZcXn;dgbViXjgIdiVa3 18;;>A: 68I>DC 2 ¹lg^iZº ;>A:2º6eea^XVi^dc#LdgY#higIZbe9^gQÄabWjY\ZiQldgYQYdXjbZci#mbaº DJIEJI2ºidHig^c\MBA9dXº3 18;O>E 68I>DC2ºo^eº HIDG:E6I=2ºnZhº ;>A:2º6eea^XVi^dc#LdgY#higDjieji9^gQ;>ABWJ9DC2ºlg^iZº ;>A:C6B:2ºhig;^aZCVbZº C6B:2ºmahh;^abhº H=::IC6B:2º;^abhº DK:GLG>I:2igjZ3
After you have run this script, you will be able to open the spreadsheet file in Excel and view the newly created workbook with the worksheet called Films (Figure 67.6). You have now created, populated, and written a spreadsheet. We are now on our way to rapidly developing a dynamic spreadsheet with multiple sheets. For demonstration purposes, we will save the file, and from now on we will read from the newly created spreadsheet file. =`^li\ -.%The data that was populated by Listing 67.7.
EFK
EI3
Populating a Spreadsheet
C`jk`e^ -.%/
(continued)
hig;^aZCVbZ2DC2ºgZVYº HG82ºhig;^aZCVbZº H=::IC6B:2º;^abhº C6B:2ºmahh;^abhº $3 18;HEG:69H=::I 68I>DC2ºgZVYº HG82ºhig;^aZCVbZº H=::IC6B:2º;^abhº FJ:GN2ºfgn;^ab9ViVº $3 18;9JBE K6G2ºfgn;^ab9ViVº $3 18;9JBE K6G2ºmahh;^abhº $3
=`^li\ -.%. The dump of the spreadsheet object and the query.
EFK
DC2ºGZVYº tag is then filtered for the desired information, as can be seen in Figure 67.8. The code then queries the database for film, expenses, directors, and actor data and uses the HegZVYh]ZZi6YYgdl function to individually populate the spreadsheet cells. C`jk`e^ -.%0
EdejaViZHegZVYh]ZZi#X[b —Populating
the Film Worksheet
1"""" ;^aZ cVbZ/ EdejaViZHegZVYh]ZZi#X[b EjgedhZ/ EdejaViZ V hegZVYh]ZZi ÄaZ 6ji]dg/ BVii IViVb """"3 18;E6G6B C6B:2ºjga#;^ab>9º 9:;6JAI2º'º $3 1""" GZVY VcY edejaViZ i]Z hegZVYh]ZZi dW_ZXi VcY fjZgn [gdb i]Z ldg`h]ZZi Äabh """3 18;H8G>EI3 hig;^aZCVbZ;gdb2GHIC6B: A6HIC6B:º $3 1$8;ADDE3 18;H8G>EI3 HegZVYh]ZZi6YY8dajbcmahh;^abh! ¹hig8HK9^gZXidghº!^ciGDL8djci9^gZXidghHiVgi!'!; VahZ0 ^ciGDL8djci6XidghHiVgi 2 ^ciGDL8djci9^gZXidghHiVgi fgn;^ab9^gZXidgh# GZXdgY8djci & 0 HegZVYh]ZZi6YYgdlmahh;^abh! ¹6Xidgh/º!^ciGDL8djci6XidghHiVgi!&!;VahZ0 hig8HK6Xidgh 2 ¹º0 1$8;H8G>EI3
18;ADDE FJ:GN2ºfgn;^ab6Xidghº3 18;H:I hig8HK6Xidgh 2 ¹hig8HK6Xidgh!C6B:;>GHI C6B:A6HIº $3 1$8;ADDE3 18;H8G>EI3 HegZVYh]ZZi6YY8dajbcmahh;^abh! ¹hig8HK6Xidghº!^ciGDL8djci6XidghHiVgi!'!;VahZ0 1$8;H8G>EI3 1"" lg^iZ i]Z ;^ab ldg`h]ZZi ^c[dgbVi^dc """3 18;HEG:69H=::I 68I>DC2ºlg^iZº ;>A:C6B:2ºhig;^aZCVbZIdº C6B:2ºmahh;^abhº DK:GLG>I:2igjZ3
487
488
CHAPTER
67
Integrating with Microsoft Office
=`^li\ -.%/ The Films worksheet.
The HegZVYh]ZZi6YY8dajbc function has the same parameters as the HegZVYh]ZZi6YYGdl function: HegZVYh]ZZi6YY8dajbcmahhDW_!higYViVP!^cihiVgi^c\gdl!^cihiVgiXdajbc! W^chZgiR
The first two parameters are a spreadsheet object and the data to populate the rows. This data is a comma-delimited list with each value representing a row. Again, the optional parameters for this function allow for us to specify the cell location to add the data and whether it will be an insert. In Listing 67.9, for demonstration purposes, we use a query to create a comma-delimited list of directors and actors and pass it as the higYViV parameter to the HegZVYh]ZZi6YY8dajbc function. We also determine the start rows for actors by evaluating how many directors there are and starting the actor information after the director section.
:i\Xk`e^ Xe 8[[`k`feXc Jgi\X[j_\\k `e X Jgi\X[j_\\k FYa\Zk Most spreadsheet workbooks contain more than one spreadsheet. As previously discussed, this chapter’s listings create four worksheets within a spreadsheet document. To do this requires us to create a new worksheet using the HegZVYh]ZZi8gZViZH]ZZi function. The syntax is as follows: HegZVYh]ZZi8gZViZH]ZZimahhDW_! Phigh]ZZicVbZR
Although the sheet name is optional, I prefer to provide one (unless the functional specification states otherwise). After the new worksheet is created, we need to be able to define in a spreadsheet object what sheet we are manipulating. The function HegZVYh]ZZiHZi6Xi^kZH]ZZimahhDW_! high]ZZicVbZ gives us the option to set the sheet as active, so any further calls to this spreadsheet object will manipulate the designated sheet.
Adding Formulas to Cells
The next worksheet we will create will list all expenses related to the specific film. The spreadsheet will also consist of the last cell (Amount column) that will display the sum of all expenses using a spreadsheet formula. The worksheet will look like Figure 67.9. Listing 67.10 adds a new sheet and then sets the active sheet to the newly created Expenses worksheet. After the sheet is set as active, the code populates and manipulates the active sheet’s data and formulas. =`^li\ -.%0 The Expenses worksheet.
8[[`e^ =fidlcXj kf :\ccj Most spreadsheets do not consist of just data. They also consist of cells that have formulas assigned to them. These formulas are one of the features that separate a spreadsheet from a simple CSV file. Among the new spreadsheet functions are the setter and getter for these cell formulas. The following is the syntax for both: HegZVYh]ZZiHZi8Zaa;dgbjaVmahhDW_! hig[dgbjaV! ^cigdl! ^ciXdajbc HegZVYh]ZZiEI3 hig;^aZCVbZ;gdb2:I>IA:! 8DAT+ higE>I8=I:MI! 8DAT) ^ci6BDJCI7J9C< ;GDB fgn;^ab9ViV L=:G: 8DAT& 2 »jga#;^ab>9¼ 1$8;FJ:GN3 18;FJ:GN 96I6HDJG8: 2 ¹DLHº C6B:2ºfgn:meZchZhº3 HZaZXi hjb:ME:CH:6BDJCI ^ci:ME:CH:6BDJCI ;GDB :meZchZh L=:G: ;^ab>9 2 JGA#;^ab>9 1$8;FJ:GN3 18;FJ:GN 96I6HDJG8: 2 ¹DLHº C6B:2ºfgn;^ab9^gZXidghº3 H:A:8I 9^gZXidgh# ;GDB Äabh >CC:G ?D>C ;^abh9^gZXidgh DC Äabh#;>AB>9 2 ;^abh9^gZXidgh#;>AB>9 >CC:G ?D>C 9^gZXidgh DC 9^gZXidgh#9^gZXidg>9 2 ;^abh9^gZXidgh#9>G:8IDG>9 L=:G: ;^abh#Äab>9 2 JGA#;^ab>9 1$8;FJ:GN3 18;FJ:GN 96I6HDJG8: 2 ¹DLHº C6B:2ºfgn;^ab6Xidghº3 H:A:8I 9>HI>C8I 68IDGH#C6B:;>GHI! 68IDGH#C6B:A6HI ;GDB ;^abh >CC:G ?D>C ;^abh6Xidgh DC Äabh#;>AB>9 2 ;^abh#;^ab>9 >CC:G ?D>C 68IDGH DC ;^abh6Xidgh#68IDG>9 2 6Xidgh#6Xidg>9 L=:G: ;^abh#Äab>9 2 JGA#;^ab>9 1$8;FJ:GN3
18;H8G>EI3 mahh;^abh 2 HegZVYh]ZZiCZl¹;^abhº!igjZ0 HegZVYh]ZZi6YYgdlmahh;^abh! ¹CVbZ/!gZeaVXZfgnTfgn;^ab9ViV#higBDK>:I>IA:! ¹!º!º ¹!ºVaaºº!&!&0 HegZVYh]ZZi6YYgdlmahh;^abh! ¹HjbbVgn/!gZeaVXZfgnTfgn;^ab9ViV#higE>I8=I:MI! ¹!º!º ¹!ºVaaºº!'!&0 $$HegZVYh]ZZi6YYgdl k^Zlh V XdbbV ^c i]Z YViV Vh V cZl Xdajbc HegZVYh]ZZi6YYgdlmahh;^abh! ¹7jY\Zi/!fgnTfgn;^ab9ViV#^ci6BDJCI7J9CEI3
18;ADDE FJ:GN2ºfgn;^ab6Xidghº3 18;H:I hig8HK6Xidgh 2 ¹hig8HK6Xidgh!C6B:;>GHI C6B:A6HIº $3 1$8;ADDE3 18;H8G>EI3 HegZVYh]ZZi6YY8dajbcmahh;^abh! ¹hig8HK6Xidghº!^ciGDL8djci6XidghHiVgi!'!;VahZ0 1$8;H8G>EI3
1""" CZl Ldg`h]ZZi ¹:meZchZhº ^c i]Z HegZVYh]ZZi dW_ZXi """3 18;FJ:GN 96I6HDJG8: 2 ¹DLHº C6B:2ºfgn;^ab:meZchZhº3 HZaZXi :ME:CH:96I: ! 9:H8G>EI>DC! :ME:CH:6BDJCI ;GDB :meZchZh L=:G: ;^ab>9 2 JGA#;^ab>9 1$8;FJ:GN3 1""" EgZeVgZ i]Z :meZchZh h]ZZi """3 18;H8G>EI3 HegZVYh]ZZi8gZViZH]ZZimahh;^abh! ¹:meZchZhº0 HegZVYh]ZZiHZi6Xi^kZH]ZZimahh;^abh! ¹:meZchZhº0 HegZVYh]ZZi6YYgdlmahh;^abh ! ¹9ViZ! 9ZhXg^ei^dc!6bdjciº 0 HegZVYh]ZZi6YYgdlhmahh;^abh ! fgn;^ab:meZchZh!'!&0 ^ci:meZchZh8djci 2 fgn;^ab:meZchZh#GZXdgY8djci0 HegZVYh]ZZiHZi8Zaa;dgbjaVmahh;^abh! ¹HJB8'/8º ^ci^ci:meZchZh8djci & ¹º! ^ci^ci:meZchZh8djci '! (0 1$8;H8G>EI3 18;FJ:GN 96I6HDJG8: 2 ¹DLHº C6B:2ºfgn;^abBZgX]VcY^hZº3 HZaZXi B:G8=C6B:! B:G8=9:H8G>EI>DC! B:G8=EG>8:! DG9:GFIN ;GDB BZgX]VcY^hZ A:;I ?D>C BZgX]VcY^hZDgYZgh>iZbh DC BZgX]VcY^hZ#BZgX]>9 2 BZgX]VcY^hZDgYZgh>iZbh# >iZb>9 A:;I ?D>C BZgX]VcY^hZDgYZgh DC BZgX]VcY^hZDgYZgh#DgYZg>9 2 BZgX]VcY^hZDgYZgh>iZbh#DgYZg>9 L=:G: ;^ab>9 2 JGA#;^ab>9 1$8;FJ:GN3 1"" lg^iZ i]Z ;^ab ldg`h]ZZi ^c[dgbVi^dc """3 18;HEG:69H=::I 68I>DC2ºlg^iZº ;>A:C6B:2ºhig;^aZCVbZIdº C6B:2ºmahh;^abhº DK:GLG>I:2igjZ3
491
492
CHAPTER
67
Integrating with Microsoft Office
The worksheet, Merchandise, will have a number of formatted columns and a formula for the total. In addition, it will compute the quantity multiplied by the price to populate the Total column (Figure 67.10). As in previous examples, we will start by querying the database to create, populate, and format the desired columns in a spreadsheet object. Listing 67.11 demonstrates how to add and set as active a new sheet; it also shows one way of setting the row’s data and formula, using a query loop. =`^li\ -.%(' The Merchandise worksheet.
C`jk`e^ -.%(( 8gZViZ;dgbjaV#X[b —Setting a Cell’s Formula Within a Loop 1"""" ;^aZ cVbZ/ 8gZViZ;dgbjaV#X[b EjgedhZ/ 9ZÄcZ V hegZVYh]ZZi [dgbjaV 6ji]dg/ BVii IViVb """"3 18;E6G6B C6B:2ºjga#;^ab>9º 9:;6JAI2º'º $3 1""" GZVY VcY edejaViZ i]Z hegZVYh]ZZi dW_ZXi VcY fjZgn [gdb i]Z ldg`h]ZZi Äabh """3 18;H8G>EI3 hig;^aZCVbZ;gdb2GHIC6B: A6HIC6B:º $3 1$8;ADDE3 18;H8G>EI3 HegZVYh]ZZi6YY8dajbcmahh;^abh! ¹hig8HK9^gZXidghº!^ciGDL8djci9^gZXidghHiVgi!'!; VahZ0 ^ciGDL8djci6XidghHiVgi 2 ^ciGDL8djci9^gZXidghHiVgi fgn;^ab9^gZXidgh# GZXdgY8djci & 0 HegZVYh]ZZi6YYgdlmahh;^abh! ¹6Xidgh/º!^ciGDL8djci6XidghHiVgi!&!;VahZ0 hig8HK6Xidgh 2 ¹º0 1$8;H8G>EI3
18;ADDE FJ:GN2ºfgn;^ab6Xidghº3 18;H:I hig8HK6Xidgh 2 ¹hig8HK6Xidgh!C6B:;>GHI C6B:A6HIº $3 1$8;ADDE3 18;H8G>EI3 HegZVYh]ZZi6YY8dajbcmahh;^abh! ¹hig8HK6Xidghº!^ciGDL8djci6XidghHiVgi!'!;VahZ0
493
494
CHAPTER
67
C`jk`e^ -.%((
Integrating with Microsoft Office
(continued)
1$8;H8G>EI3
1""" CZl Ldg`h]ZZi ¹:meZchZhº ^c i]Z HegZVYh]ZZi dW_ZXi """3 18;FJ:GN 96I6HDJG8: 2 ¹DLHº C6B:2ºfgn;^ab:meZchZhº3 HZaZXi :ME:CH:96I: ! 9:H8G>EI>DC! :ME:CH:6BDJCI ;GDB :meZchZh L=:G: ;^ab>9 2 JGA#;^ab>9 1$8;FJ:GN3 1""" EgZeVgZ i]Z :meZchZh h]ZZi """3 18;H8G>EI3 HegZVYh]ZZi8gZViZH]ZZimahh;^abh! ¹:meZchZhº0 HegZVYh]ZZiHZi6Xi^kZH]ZZimahh;^abh! ¹:meZchZhº0 HegZVYh]ZZi6YYgdlmahh;^abh ! ¹9ViZ! 9ZhXg^ei^dc!6bdjciº 0 HegZVYh]ZZi6YYgdlhmahh;^abh ! fgn;^ab:meZchZh!'!&0 ^ci:meZchZh8djci 2 fgn;^ab:meZchZh#GZXdgY8djci0 HegZVYh]ZZiHZi8Zaa;dgbjaVmahh;^abh! ¹HJB8'/8º ^ci^ci:meZchZh8djci & ¹º! ^ci^ci:meZchZh8djci '! (0 1$8;H8G>EI3 18;FJ:GN 96I6HDJG8: 2 ¹DLHº C6B:2ºfgn;^abBZgX]VcY^hZº3 HZaZXi B:G8=C6B:! B:G8=9:H8G>EI>DC! B:G8=EG>8:! DG9:GFIN ;GDB BZgX]VcY^hZ A:;I ?D>C BZgX]VcY^hZDgYZgh>iZbh DC BZgX]VcY^hZ#BZgX]>9 2 BZgX]VcY^hZDgYZgh>iZbh# >iZb>9 A:;I ?D>C BZgX]VcY^hZDgYZgh DC BZgX]VcY^hZDgYZgh#DgYZg>9 2 BZgX]VcY^hZDgYZgh>iZbh#DgYZg>9 L=:G: ;^ab>9 2 JGA#;^ab>9 1$8;FJ:GN3 1""" EgZeVgZ i]Z BZgX]VcY^hZ h]ZZi """3 18;H8G>EI3 HegZVYh]ZZi8gZViZH]ZZimahh;^abh! ¹BZgX]VcY^hZº0 HegZVYh]ZZiHZi6Xi^kZH]ZZimahh;^abh! ¹BZgX]VcY^hZº0 ^ci8jggZciGdl 2 &0 HegZVYh]ZZi6YYgdlmahh;^abh ! ¹CVbZ! 9ZhXg^ei^dc!Eg^XZ! FjVci^in HdaY!IdiVaº 0 1$8;H8G>EI3 18;ADDE FJ:GN2ºfgn;^abBZgX]VcY^hZº3 18;H8G>EI3 ^ci8jggZciGdl 2 ^ci8jggZciGdl &0 HegZVYh]ZZi6YYgdlmahh;^abh ! ¹gZeaVXZB:G8=C6B:! ¹!º!º ¹!ºVaaº!gZeaVXZB:G8 =9:H8G>EI>DC! ¹!º!º ¹!ºVaaº!B:G8=EG>8:! DG9:GFINº !^ci8jggZciGdl !&0 HegZVYh]ZZiHZi8Zaa;dgbjaVmahh;^abh! ¹8º ^ci8jggZciGdl ¹9º ^ci8jggZciGdl ¹º! ^ci8jggZciGdl! *0 1$8;H8G>EI3 1$8;ADDE3
1"" lg^iZ i]Z ;^ab ldg`h]ZZi ^c[dgbVi^dc """3 18;HEG:69H=::I 68I>DC2ºlg^iZº ;>A:C6B:2ºhig;^aZCVbZIdº C6B:2ºmahh;^abhº DK:GLG>I:2igjZ3
Adding Formatting to Cells
8[[`e^ =fidXkk`e^ kf :\ccj The Merchandise Order worksheet is similar to the Expenses worksheet with the date and currency format and a Total cell (which we will top with a double rule, as in Figure 67.11). Listing 67.12 shows how to format a particular cell. Some of the new functions for formatting a particular cell are as follows: HegZVYh]ZZi;dgbVi8Zaa, HegZVYh]ZZi;dgbVi8dajbc, HegZVYh]ZZi ;dgbVi8dajbch, HegZVYh]ZZi;dgbViGdl, HegZVYh]ZZi;dgbViGdlh# All of these functions require the spreadsheet object as well as a structure that represents a cell, row, or column format. Table 67.2 lists the name-value pairs that can optionally be specified. We must first create the format structure using [biIdiVa8dajbc2HigjXiCZl 0
Then we will assign a name-value pair that formats the data: [biIdiVa8dajbc#YViV;dgbVi 2 ¹!%#%%º0 [biIdiVa8dajbc#Ide7dgYZg2ºYdjWaZº0
Then we will apply the format to the specific cell: HegZVYh]ZZi;dgbVi8dajbchmahh;^abh![biIdiVa8dajbc!(0
After the spreadsheet has been manipulated, we need to the use the 8;HEG:69H=::I tag to write it to the file system. KXYc\ -.%)
The Format Struct Name and Value Pairs
NAME
VALUES
Va^\cbZci
aZ[iYZ[Vjai! XZciZg! XZciZgThZaZXi^dc! Äaa! \ZcZgVa! _jhi^[n! g^\]i! kZgi^XVaTWdiidb! kZgi^XVaTXZciZg! kZgi^XVaT_jhi^[n! kZgi^XVaTide
WdaY
[VahZYZ[Vjai! igjZ
WdiidbWdgYZg
cdcZYZ[Vjai! YVh]ZY!YVh]TYdi! YVh]TYdiTYdi! YdiiZY! YdjWaZ! ]V^g! bZY^jb! bZY^jbTYVh]TYdi! bZY^jbTYVh]TYdiT Ydi! bZY^jbTYVh]ZY! haVciZYTYVh]TYdi! i]^X`! i]^c
WdiidbWdgYZgXdadg
As per Xdadg values (dg\#VeVX]Z#ed^#]hh[#ji^a#=HH;8dadg)
Xdadg
As per Xdadg values (dg\#VeVX]Z#ed^#]hh[#ji^a#=HH;8dadg) VfjV! WaVX`! WajZ! WajZT\gZn! Wg^\]iT\gZZc! Wgdlc! XdgVa! XdgcÅdlZgTWajZ! YVg`TWajZ! YVg`T\gZZc! YVg`TgZY! YVg`TiZVa! YVg`TnZaadl! \daY! \gZZc! \gZnT'*TeZgXZci! \gZnT)%TeZgXZci!\gZnT*%TeZgXZci! \gZnT-%TeZgXZci! ^cY^\d! aVkZcYZg! aZbdcTX]^[[dc! a^\]iTWajZ! a^\]iTXdgcÅdlZgTWajZ! a^\]iT\gZZc! a^\]iTdgVc\Z! a^\]iTijgfjd^hZ! a^\]iTnZaadl! a^bZ! bVgddc! da^kZT\gZZc! dgVc\Z! dgX]^Y! eVaZTWajZ! e^c`! eajb! gZY! gdhZ! gdnVaTWajZ! hZVT\gZZc! h`nTWajZ! iZVa! ijgfjd^hZ! k^daZi! l]^iZ! nZaadl
YViV[dgbVi
Most Excel formats are supported: , %#%%, Y"bbb"nn, and so on see CFML Reference for more)
[\Xdadg
As per Xdadg values (dg\#VeVX]Z#ed^#]hh[#ji^a#=HH;8dadg)
495
496
CHAPTER
67
KXYc\ -.%)
Integrating with Microsoft Office
(continued)
NAME
VALUES
ÄaaeViiZgc
W^\ThedihYZ[Vjai! VaiTWVgh! Y^VbdcYh! ÄcZTYdih! aZVhiT Ydih! aZhhTYdih! cdÄaa! hda^YT[dgZ\gdjcY! heVghZTYdih! hfjVgZh! i]^X`TWVX`lVgYTY^V\! i]^X`T[dglVgYTY^V\! i]^X`T ]dgoTWVcYh! i]^X`TkZgiTWVcYh
[dci
Name of a font
[dcih^oZ
Size of the font (point size)
]^YYZc
[VahZ (default) or igjZ
^cYZci
Number of spaces to indent
^iVa^X
[VahZ (default) or igjZ
aZ[iWdgYZg
As per WdiidbWdgYZg values
aZ[iWdgYZgXdadg
As per Xdadg values
adX`ZY
[VahZ (default) or igjZ
g^\]iWdgYZg
As per WdiidbWdgYZg values
g^\]iWdgYZgXdadg
As per Xdadg values
gdiVi^dc
Integer representing the number of degrees in the range –90 to 90
hig^`Zdji
[VahZ (default) or igjZ
iZmilgVe
[VahZ (default) or igjZ
ideWdgYZg
As per WdiidbWdgYZg values
ideWdgYZgXdadg
As per Xdadg values
jcYZga^cZ
[VahZ (default) or igjZ
=`^li\ -.%(( The Merchandise Order spreadsheet.
C`jk`e^ -.%()
;dgbVi8Zaa#X[b —Formatting
a Cell
1"""" ;^aZ cVbZ/ ;dgbVi8Zaa#X[b EjgedhZ/ ;dgbVi V hegZVYh]ZZi ÄaZ XZaa 6ji]dg/ BVii IViVb """"3
Adding Formatting to Cells
C`jk`e^ -.%()
(continued)
18;E6G6B C6B:2ºjga#;^ab>9º 9:;6JAI2º'º $3 1""" GZVY VcY edejaViZ i]Z hegZVYh]ZZi dW_ZXi VcY fjZgn [gdb i]Z ldg`h]ZZi Äabh """3 18;H8G>EI3 hig;^aZCVbZ;gdb2:I>IA:! 8DAT+ higE>I8=I:MI! 8DAT) ^ci6BDJCI7J9C< ;GDB fgn;^ab9ViV L=:G: 8DAT& 2 »jga#;^ab>9¼ 1$8;FJ:GN3 18;FJ:GN 96I6HDJG8: 2 ¹DLHº C6B:2ºfgn:meZchZhº3 HZaZXi hjb:ME:CH:6BDJCI ^ci:ME:CH:6BDJCI ;GDB :meZchZh L=:G: ;^ab>9 2 JGA#;^ab>9 1$8;FJ:GN3 18;FJ:GN 96I6HDJG8: 2 ¹DLHº C6B:2ºfgn;^ab9^gZXidghº3 H:A:8I 9^gZXidgh# ;GDB Äabh >CC:G ?D>C ;^abh9^gZXidgh DC Äabh#;>AB>9 2 ;^abh9^gZXidgh#;>AB>9 >CC:G ?D>C 9^gZXidgh DC 9^gZXidgh#9^gZXidg>9 2 ;^abh9^gZXidgh#9>G:8IDG>9 L=:G: ;^abh#Äab>9 2 JGA#;^ab>9 1$8;FJ:GN3 18;FJ:GN 96I6HDJG8: 2 ¹DLHº C6B:2ºfgn;^ab6Xidghº3 H:A:8I 9>HI>C8I 68IDGH#C6B:;>GHI! 68IDGH#C6B:A6HI ;GDB ;^abh >CC:G ?D>C ;^abh6Xidgh DC Äabh#;>AB>9 2 ;^abh#;^ab>9 >CC:G ?D>C 68IDGH DC ;^abh6Xidgh#68IDG>9 2 6Xidgh#6Xidg>9 L=:G: ;^abh#Äab>9 2 JGA#;^ab>9 1$8;FJ:GN3
18;H8G>EI3 mahh;^abh 2 HegZVYh]ZZiCZl¹;^abhº!igjZ0 HegZVYh]ZZi6YYgdlmahh;^abh! ¹CVbZ/!gZeaVXZfgnTfgn;^ab9ViV#higBDK>:I>IA:! ¹!º!º ¹!ºVaaºº!&!&0 HegZVYh]ZZi6YYgdlmahh;^abh! ¹HjbbVgn/!gZeaVXZfgnTfgn;^ab9ViV#higE>I8=I:MI! ¹!º!º ¹!ºVaaºº!'!&0 $$HegZVYh]ZZi6YYgdl k^Zlh V XdbbV ^c i]Z YViV Vh V cZl Xdajbc
497
498
CHAPTER
67
C`jk`e^ -.%()
Integrating with Microsoft Office
(continued)
HegZVYh]ZZi6YYgdlmahh;^abh! HegZVYh]ZZi6YYgdlmahh;^abh! HegZVYh]ZZi6YYgdlmahh;^abh! HegZVYh]ZZi6YYgdlmahh;^abh!
¹7jY\Zi/!fgnTfgn;^ab9ViV#^ci6BDJCI7J9CEI3 18;ADDE FJ:GN2ºfgn;^ab9^gZXidghº3 18;H:I hig8HK9^gZXidgh 2 ¹hig8HK9^gZXidgh!;>GHIC6B: A6HIC6B:º $3 1$8;ADDE3 18;H8G>EI3 HegZVYh]ZZi6YY8dajbcmahh;^abh! ¹hig8HK9^gZXidghº!^ciGDL8djci9^gZXidghHiVgi!'!; VahZ0 ^ciGDL8djci6XidghHiVgi 2 ^ciGDL8djci9^gZXidghHiVgi fgn;^ab9^gZXidgh# GZXdgY8djci & 0 HegZVYh]ZZi6YYgdlmahh;^abh! ¹6Xidgh/º!^ciGDL8djci6XidghHiVgi!&!;VahZ0 hig8HK6Xidgh 2 ¹º0 1$8;H8G>EI3
18;ADDE FJ:GN2ºfgn;^ab6Xidghº3 18;H:I hig8HK6Xidgh 2 ¹hig8HK6Xidgh!C6B:;>GHI C6B:A6HIº $3 1$8;ADDE3 18;H8G>EI3 HegZVYh]ZZi6YY8dajbcmahh;^abh! ¹hig8HK6Xidghº!^ciGDL8djci6XidghHiVgi!'!;VahZ0 1$8;H8G>EI3
1""" CZl Ldg`h]ZZi ¹:meZchZhº ^c i]Z HegZVYh]ZZi dW_ZXi """3 18;FJ:GN 96I6HDJG8: 2 ¹DLHº C6B:2ºfgn;^ab:meZchZhº3 HZaZXi :ME:CH:96I: ! 9:H8G>EI>DC! :ME:CH:6BDJCI ;GDB :meZchZh L=:G: ;^ab>9 2 JGA#;^ab>9 1$8;FJ:GN3 1""" EgZeVgZ i]Z :meZchZh h]ZZi """3 18;H8G>EI3 HegZVYh]ZZi8gZViZH]ZZimahh;^abh! ¹:meZchZhº0 HegZVYh]ZZiHZi6Xi^kZH]ZZimahh;^abh! ¹:meZchZhº0 HegZVYh]ZZi6YYgdlmahh;^abh ! ¹9ViZ! 9ZhXg^ei^dc!6bdjciº 0 HegZVYh]ZZi6YYgdlhmahh;^abh ! fgn;^ab:meZchZh!'!&0 ^ci:meZchZh8djci 2 fgn;^ab:meZchZh#GZXdgY8djci0 HegZVYh]ZZiHZi8Zaa;dgbjaVmahh;^abh! ¹HJB8'/8º ^ci^ci:meZchZh8djci & ¹º! ^ci^ci:meZchZh8djci '! (0 1$8;H8G>EI3 18;FJ:GN 96I6HDJG8: 2 ¹DLHº C6B:2ºfgn;^abBZgX]VcY^hZº3 HZaZXi B:G8=C6B:! B:G8=9:H8G>EI>DC! B:G8=EG>8:! DG9:GFIN ;GDB BZgX]VcY^hZ A:;I ?D>C BZgX]VcY^hZDgYZgh>iZbh DC BZgX]VcY^hZ#BZgX]>9 2 BZgX]VcY^hZDgYZgh>iZbh# >iZb>9 A:;I ?D>C BZgX]VcY^hZDgYZgh DC BZgX]VcY^hZDgYZgh#DgYZg>9 2 BZgX]VcY^hZDgYZgh>iZbh#DgYZg>9 L=:G: ;^ab>9 2 JGA#;^ab>9
Adding Formatting to Cells
C`jk`e^ -.%()
(continued)
1$8;FJ:GN3 1""" EgZeVgZ i]Z BZgX]VcY^hZ h]ZZi """3 18;H8G>EI3 HegZVYh]ZZi8gZViZH]ZZimahh;^abh! ¹BZgX]VcY^hZº0 HegZVYh]ZZiHZi6Xi^kZH]ZZimahh;^abh! ¹BZgX]VcY^hZº0 ^ci8jggZciGdl 2 &0 HegZVYh]ZZi6YYgdlmahh;^abh ! ¹CVbZ! 9ZhXg^ei^dc!Eg^XZ! FjVci^in HdaY!IdiVaº 0 1$8;H8G>EI3 18;ADDE FJ:GN2ºfgn;^abBZgX]VcY^hZº3 18;H8G>EI3 ^ci8jggZciGdl 2 ^ci8jggZciGdl &0 HegZVYh]ZZi6YYgdlmahh;^abh ! ¹gZeaVXZB:G8=C6B:! ¹!º!º ¹!ºVaaº!gZeaVXZB:G8 =9:H8G>EI>DC! ¹!º!º ¹!ºVaaº!B:G8=EG>8:! DG9:GFINº !^ci8jggZciGdl !&0 HegZVYh]ZZiHZi8Zaa;dgbjaVmahh;^abh! ¹8º ^ci8jggZciGdl ¹9º ^ci8jggZciGdl ¹º! ^ci8jggZciGdl! *0 1$8;H8G>EI3 1$8;ADDE3 18;FJ:GN 96I6HDJG8: 2 ¹DLHº C6B:2ºfgnBZgX]VcY^hZDgYZghº3 H:A:8I 8dciVXih#;^ghiCVbZ! 8dciVXih#AVhiCVbZ ! hjbBZgX]VcY^hZDgYZgh>iZbh# DgYZgFin BZgX]VcY^hZDgYZgh>iZbh#>iZbEg^XZ Vh DgYZgIdiVa ! BZgX]VcY^hZDgYZgh# H]^eHiViZ! BZgX]VcY^hZDgYZgh#H]^e8djcign! BZgX]VcY^hZDgYZgh#H]^eO^e! BZgX]VcY^hZDgYZgh#H]^e9ViZ ;GDB 8dciVXih >CC:G ?D>C BZgX]VcY^hZDgYZgh DC 8dciVXih#8dciVXi>9 2 BZgX]VcY^hZDgYZgh#8dciVXi>9 >CC:G ?D>C BZgX]VcY^hZ >CC:G ?D>C BZgX]VcY^hZDgYZgh>iZbh DC BZgX]VcY^hZ#BZgX]>9 2 BZgX]VcY^hZDgYZgh>iZbh#>iZb>9 DC BZgX]VcY^hZDgYZgh#DgYZg>9 2 BZgX]VcY^hZDgYZgh>iZbh#DgYZg>9 EI3 HegZVYh]ZZi8gZViZH]ZZimahh;^abh! ¹BZgX]VcY^hZ DgYZghº0 HegZVYh]ZZiHZi6Xi^kZH]ZZimahh;^abh! ¹BZgX]VcY^hZ DgYZghº0 HegZVYh]ZZi6YYgdlmahh;^abh ! ¹;^ghi CVbZ! AVhi CVbZ! DgYZg IdiVa! HiViZ! 8djcign! O^e! H]^ee^c\ 9ViZº 0 HegZVYh]ZZi6YYgdlhmahh;^abh ! fgnBZgX]VcY^hZDgYZgh 0 ^ciBZgX]VcY^hZDgYZgh8djci 2 fgnBZgX]VcY^hZDgYZgh#GZXdgY8djci0 HegZVYh]ZZiHZi8Zaa;dgbjaVmahh;^abh! ¹HJB8'/8º ^ci^ciBZgX]VcY^hZDgYZgh8djci & ¹º! ^ci^ciBZgX]VcY^hZDgYZgh8djci '! (0 $$;dgbVih i]Z DgYZg IdiVa Xdajbc id cjbZg^X [biIdiVa8dajbc2HigjXiCZl 0 [biIdiVa8dajbc#YViV;dgbVi 2 ¹!%#%%º0 HegZVYh]ZZi;dgbVi8dajbchmahh;^abh![biIdiVa8dajbc!(0 $$;dgbVih i]Z H]^ee^c\ YViV Xdajbc id 9ViZ [bi9ViZ8dajbc2HigjXiCZl 0 [bi9ViZ8dajbc#YViV;dgbVi 2 ¹Y"bbb"nnº 0 HegZVYh]ZZi;dgbVi8dajbchmahh;^abh! [bi9ViZ8dajbc!,0
499
500
CHAPTER
67
C`jk`e^ -.%()
Integrating with Microsoft Office
(continued)
$$;dgbVih i]Z DgYZg IdiVa Xdajbc id cjbZg^X VcY ]Vh V YdjWaZ ide WdgYZg [biIdiVa8dajbc2HigjXiCZl 0 [biIdiVa8dajbc#YViV;dgbVi 2 ¹!%#%%º0 [biIdiVa8dajbc#Ide7dgYZg2ºYdjWaZº0 HegZVYh]ZZi;dgbVi8Zaamahh;^abh![biIdiVa8dajbc!^ci^ciBZgX]VcY^hZDgYZgh8djci (0
'!
1$8;H8G>EI3
1"" lg^iZ i]Z ;^ab ldg`h]ZZi ^c[dgbVi^dc """3 18;HEG:69H=::I 68I>DC2ºlg^iZº ;>A:C6B:2ºhig;^aZCVbZIdº C6B:2ºmahh;^abhº DK:GLG>I:2igjZ3
8lkfdXk`fe Automation is the process of launching another application and controlling it programmatically through a public interface. All Office applications support automation and provide a COM interface that is accessible from ColdFusion. However, when an Office application is launched through automation, the resources and effect are the same as when the application is launched by a loggedin user. This behavior poses many problems for server-side integration, as with ColdFusion. The fact that there is no logged-in user can, in some circumstances, cause the Office application to lock up on launch, and lockups will occur at any point during use if an error message presents a modal dialog; the dialog will pop up and wait for a user to dismiss it. This behavior can pose a serious problem if someone isn’t sitting at the server constantly. The same is true if the application runs into a feature that isn’t installed and presents the Install on First Use dialog. Besides these serious problems, automation also presents concerns over scalability and security. The best recommendation regarding server-side automation of Microsoft Office applications comes directly from Microsoft: Microsoft does not currently recommend, and does not support, Automation of Microsoft Office applications from any unattended, non-interactive client application or component (including ASP, DCOM, and NT Services), because Office may exhibit unstable behavior and/or deadlock when run in this environment. ]iie/$$hjeedgi#b^Xgdhd[i#Xdb$YZ[Vjai#Vhem4hX^Y2`W0Zc"jh0'*,,*,
Microsoft makes this recommendation regarding its technology, but this recommendation applies equally to ColdFusion, Java, and all other server-side programming technologies.
:?8GKbV\Z """3 1X[[jcXi^dc cVbZ2º\Zi=^hid\gVb>bV\Zº VXXZhh2ºejWa^Xº gZijgcineZ2ºVcnº djieji2º[VahZº ]^ci2º> XgZViZ V Xdadg ]^hid\gVb ECbV\Zº gZfj^gZY2ºnZhº ineZ2ºhig^c\º ]^ci2º;^aZcVbZ VcY eVi] d[ ^bV\Z id XgZViZ ]^hid\gVb d[º $3 1X[Vg\jbZci cVbZ2ºl^Yi]º gZfj^gZY2ºnZhº YZ[Vjai2º'*+º ineZ2ºcjbZg^Xº ]^ci2º]Z^\]i d[ ec\ id XgZViZº $3 1X[Vg\jbZci cVbZ2º]Z^\]iº gZfj^gZY2ºnZhº YZ[Vjai2º&'%º ineZ2ºcjbZg^Xº ]^ci2º]Z^\]i d[ ec\ id XgZViZº $3 1X[hXg^ei3 $$XgZViZ Xdadg ]^hi\gVb kVg ]^hid\gVb 2 \Zi=^hid\gVbVg\jbZcih#^ceji>bV\Z0 $$YgVl VcY gZijgc ^bV\Z gZijgc YgVl=^hid\gVb]^hid\gVb!Vg\jbZcih#l^Yi]!Vg\jbZcih#]Z^\]i0 1$X[hXg^ei3 1$X[[jcXi^dc3 1""" 222222222222222222222222222222222222222222222222222222222222222222222 """3 1""" \Zi8dadg=^hid\gVb>bV\Z """3 1X[[jcXi^dc cVbZ2º\Zi8dadg=^hid\gVb>bV\Zº VXXZhh2ºejWa^Xº gZijgcineZ2ºVcnº djieji2º[VahZº ]^ci2º> XgZViZ V Xdadg ]^hid\gVb ECbV\Zº gZfj^gZY2ºnZhº ineZ2ºhig^c\º ]^ci2º;^aZcVbZ VcY eVi] d[ ^bV\Z id XgZViZ ]^hid\gVb d[º $3 1X[Vg\jbZci cVbZ2ºl^Yi]º gZfj^gZY2ºnZhº YZ[Vjai2º'*+º ineZ2ºcjbZg^Xº ]^ci2º]Z^\]i d[ ec\ id XgZViZº $3 1X[Vg\jbZci cVbZ2º]Z^\]iº gZfj^gZY2ºnZhº YZ[Vjai2º&'%º ineZ2ºcjbZg^Xº ]^ci2º]Z^\]i d[ ec\ id XgZViZº $3 1X[hXg^ei3 $$XgZViZ Xdadg ]^hi\gVb kVg ]^hid\gVb 2 \Zi8dadg=^hid\gVbVg\jbZcih#^ceji>bV\Z0
509
510
CHAPTER
68
C`jk`e^ -/%*
Extending ColdFusion with Java
(continued)
$$YgVl VcY gZijgc ^bV\Z gZijgc YgVl8dadg=^hid\gVb]^hid\gVb!Vg\jbZcih#l^Yi]!Vg\jbZcih#]Z^\]i0 1$X[hXg^ei3 1$X[[jcXi^dc3 1""" 222222222222222222222222222222222222222222222222222222222222222222222 """3 1""" XgZViZ>ceji>bV\Z """3 1X[[jcXi^dc cVbZ2ºXgZViZ>ceji>bV\Zº VXXZhh2ºeg^kViZº gZijgcineZ2ºkd^Yº djieji2º[VahZº ]^ci2º> XgZViZ Vc ^bV\Z cZlº3 1X[Vg\jbZci cVbZ2º^ceji>bV\Zº gZfj^gZY2ºnZhº ineZ2ºhig^c\º YZ[Vjai2ºº ]^ci2º;^aZcVbZ VcY eVi] d[ ^bV\Z id XgZViZ ]^hid\gVb d[º $3 1X[hZi kVg^VWaZh#^ceji>bV\Z 2 ^bV\ZCZlVg\jbZcih#^ceji>bV\Z $3 1$X[[jcXi^dc3
1""" 222222222222222222222222222222222222222222222222222222222222222222222 """3 1""" hZi7j[[ZgZY>bV\Z """3 1X[[jcXi^dc cVbZ2ºhZi7j[[ZgZY>bV\Zº VXXZhh2ºejWa^Xº gZijgcineZ2ºkd^Yº djieji2º[VahZº ]^ci2º> hZi i]Z i]Z Wj[[ZgZY ^bV\Z! ^ XVc WZ jhZY ^[ ndj lVci id hZi V Wj[[ZgZY ^bV\Z ^chiZVY d[ heZX^[n^c\ V ^bV\Z ÄaZ cVbZ VcY eVi]º3 1X[Vg\jbZci cVbZ2ºWj[[ZgZY>bV\Zº gZfj^gZY2ºnZhº ]^ci2º7j[[ZgZY ^bV\Zº $3 1X[hZi kVg eW 2 ¹º $3 1X[hXg^ei3 eW 2 XgZViZDW_ZXi¹?VkVº!º_VkV#Vli#^bV\Z#gZcYZgVWaZ#EVgVbZiZg7adX`º#^c^i0 $$VYY ^bV\Z hdjgXZ eW#VYYVg\jbZcih#Wj[[ZgZY>bV\Z0 $$XgZViZ ?6> EaVcVg>bV\Z kVg^VWaZh#^ceji>bV\Z 2 kVg^VWaZh#?6>#XgZViZ¹6LI>bV\Zº! eW0 $$ kVg^VWaZh#^ceji>bV\Z>hEaVcVg>bV\Z 2 igjZ0 1$X[hXg^ei3 1$X[[jcXi^dc3 1""" 222222222222222222222222222222222222222222222222222222222222222222222 """3 1""" XgZViZ?6>=^hid\gVb """3 1X[[jcXi^dc cVbZ2ºXgZViZ?6>=^hid\gVbº VXXZhh2ºeg^kViZº gZijgcineZ2ºhigjXiº djieji2º[VahZº ]^ci2º> XgZViZ V ]^hid\gVb l^i] ?6>º3 1X[hXg^ei3 kVg de 2 ¹º0 kVg W^ch 2 ¹º0 kVg ^ 2 %0 kVg ]^hid\gVb 2 ¹º0 kVg g\W 2 ¹º0 $$XgZViZ EVgVbZiZg7adX` kVg eW 2 XgZViZDW_ZXi¹?VkVº!º_VkV#Vli#^bV\Z#gZcYZgVWaZ#EVgVbZiZg7adX`º#^c^i0 $$XgZViZ ]daYZg higjXijgZ kVg ]^hid\gVbHigjXi 2 XgZViZ=^hid\gVb=daYZgHigjXi0 $$VYY ^bV\Z hdjgXZ ^[ ^ceji>bV\Z>hEaVcVg>bV\Z p $$VagZVYn V eaVcVg ^bV\Z eW#VYYHdjgXZkVg^VWaZh#^ceji>bV\Z0 r ZahZ p $$cZZY id XdckZgi eW#VYYHdjgXZ^bV\ZbV\ZkVg^VWaZh#^ceji>bV\Z0 r
Using Java Class Objects
C`jk`e^ -/%*
(continued)
$$GZcYZgZYDe de 2 kVg^VWaZh#?6>#XgZViZ¹]^hid\gVbº! eW0 $$\Zi ]^hid\gVb _VkVm#bZY^V#_V^#=^hid\gVb ]^hid\gVb 2 de#\ZiEgdeZgin¹]^hid\gVbº0 $$]^hid\gVb W^ch " VggVnP(RP'*+R W^ch 2 ]^hid\gVb#\Zi7^ch0 $$VkZgV\Z Xdadgh ^cid h^c\aZ VggVn [dg^2&0^ AI: '*+0 ^2^ & p ]^hid\gVbHigjXi#]^hid\gVbP^R 2 GdjcYW^chP&RP^R W^chP'RP^R r $$\Zi hiVi^hi^Xh g\W 2 \Zi=^hid\gVbHiVi^hi^Xh]^hid\gVbHigjXi#]^hid\gVb0 ]^hid\gVbHigjXi#bZVc 2 g\W#bZVc0 ]^hid\gVbHigjXi#hiVcYVgYYZk^Vi^dc 2 g\W#hiVcYVgYYZk^Vi^dc0 ]^hid\gVbHigjXi#b^c 2 g\W#b^c0 ]^hid\gVbHigjXi#bVm 2 g\W#bVm0 $$gZijgc ]^hid\gVb higjXijgZ gZijgc ]^hid\gVbHigjXi0 1$X[hXg^ei3 1$X[[jcXi^dc3
W^chP(RP^R$(0
1""" 222222222222222222222222222222222222222222222222222222222222222222222 """3 1""" XgZViZ?6>8dadg=^hid\gVb """3 1X[[jcXi^dc cVbZ2ºXgZViZ?6>8dadg=^hid\gVbº VXXZhh2ºeg^kViZº gZijgcineZ2ºhigjXiº djieji2º[VahZº ]^ci2º> XgZViZ V Xdadg ]^hid\gVb l^i] ?6>º3 1X[hXg^ei3 kVg de 2 ¹º0 kVg W^ch 2 ¹º0 kVg bZVc6ggVn 2 ¹º0 kVg hY6ggVn 2 ¹º0 $$XgZViZ EVgVbZiZg7adX` kVg eW 2 XgZViZDW_ZXi¹?VkVº!º_VkV#Vli#^bV\Z#gZcYZgVWaZ#EVgVbZiZg7adX`º#^c^i0 $$XgZViZ ]daYZg higjXi [dg ]^hid\gVb kVg Xdadg=^hid\gVb 2 higjXiCZl0 $$VYY ^bV\Z hdjgXZ ^[ ^ceji>bV\Z>hEaVcVg>bV\Z p $$VagZVYn V eaVcVg ^bV\Z eW#VYYHdjgXZkVg^VWaZh#^ceji>bV\Z0 r ZahZ p $$cZZY id XdckZgi eW#VYYHdjgXZ^bV\ZbV\ZkVg^VWaZh#^ceji>bV\Z0 r $$GZcYZgZYDe de 2 kVg^VWaZh#?6>#XgZViZ¹]^hid\gVbº! eW0 $$\Zi ]^hid\gVb _VkVm#bZY^V#_V^#=^hid\gVb ]^hid\gVb 2 de#\ZiEgdeZgin¹]^hid\gVbº0 $$]^hid\gVb W^ch " VggVnP(RP'*+R W^ch 2 ]^hid\gVb#\Zi7^ch0 bZVc6ggVn 2 ]^hid\gVb#\ZiBZVc0 hY6ggVn 2 ]^hid\gVb#\ZiHiVcYVgY9Zk^Vi^dc0 $$gZY Xdadg=^hid\gVb#g#]^hid\gVb 2 W^chP&R0 Xdadg=^hid\gVb#g#bZVc 2 bZVc6ggVnP&R0 Xdadg=^hid\gVb#g#hiVcYVgYYZk^Vi^dc 2 hY6ggVnP&R0 Xdadg=^hid\gVb#g#b^c 2 VggVnB^cW^chP&R0 Xdadg=^hid\gVb#g#bVm 2 VggVnBVmW^chP&R0
511
512
CHAPTER
68
C`jk`e^ -/%*
Extending ColdFusion with Java
(continued)
$$\gZZc Xdadg=^hid\gVb#\#]^hid\gVb 2 W^chP'R0 Xdadg=^hid\gVb#\#]^hid\gVb 2 W^chP'R0 Xdadg=^hid\gVb#\#bZVc 2 bZVc6ggVnP'R0 Xdadg=^hid\gVb#\#hiVcYVgYYZk^Vi^dc 2 hY6ggVnP'R0 Xdadg=^hid\gVb#\#b^c 2 VggVnB^cW^chP'R0 Xdadg=^hid\gVb#\#bVm 2 VggVnBVmW^chP'R0 $$WajZ Xdadg=^hid\gVb#W#]^hid\gVb 2 W^chP(R0 Xdadg=^hid\gVb#W#]^hid\gVb 2 W^chP(R0 Xdadg=^hid\gVb#W#bZVc 2 bZVc6ggVnP(R0 Xdadg=^hid\gVb#W#hiVcYVgYYZk^Vi^dc 2 hY6ggVnP(R0 Xdadg=^hid\gVb#W#b^c 2 VggVnB^cW^chP(R0 Xdadg=^hid\gVb#W#bVm 2 VggVnBVmW^chP(R0 $$gZijgc ]^hid\gVb higjXijgZ gZijgc Xdadg=^hid\gVb0 1$X[hXg^ei3 1$X[[jcXi^dc3 1""" 222222222222222222222222222222222222222222222222222222222222222222222 """3 1""" YgVl=^hid\gVb """3 1X[[jcXi^dc cVbZ2ºYgVl=^hid\gVbº VXXZhh2ºeg^kViZº gZijgcineZ2ºVcnº djieji2º[VahZº ]^ci2º> YgVl V ]^hid\gVb ^bV\Zº3 1X[Vg\jbZci cVbZ2º]^hid\gVbº gZfj^gZY2ºnZhº ]^ci2º]^hid\gVbº $3 1X[Vg\jbZci cVbZ2ºl^Yi]º gZfj^gZY2ºnZhº YZ[Vjai2º'*+º ineZ2ºcjbZg^Xº ]^ci2ºl^Yi] d[ ^bV\Z id XgZViZº $3 1X[Vg\jbZci cVbZ2º]Z^\]iº gZfj^gZY2ºnZhº YZ[Vjai2º&'%º ineZ2ºcjbZg^Xº ]^ci2º]Z^\]i d[ ^bV\Z id XgZViZº $3 1X[hXg^ei3 kVg ^^ 2 ¹º0 $$XgZViZ ^bV\Z kVg ]^hi>bV\Z 2 ^bV\ZCZl¹º!'*+!Vg\jbZcih#]Z^\]i!ºVg\Wº0 $$hZi YgVl^c\ Xdadg >bV\ZHZi9gVl^c\8dadg]^hi>bV\Z!ºWaVX`º0 $$adde i]gj Vaa W^ch ^c Xdadg [dg^^2&0^^ AI: '*+0 ^^2^^ & p $$hZi bVm ]Z^\]i WVhZY dc i]Z bVm h^oZ [djcY ^c VggVn a^cZ=Z^\]i 2 Vg\jbZcih#]Z^\]i"Vg\jbZcih#]^hid\gVb#]^hid\gVbP^^R$ VggVnBVmVg\jbZcih#]^hid\gVb#]^hid\gVb Vg\jbZcih#]Z^\]i0 $$YgVl a^cZ ^bV\Z9gVlA^cZ]^hi>bV\Z!^^"&!Vg\jbZcih#]Z^\]i!^^"&!a^cZ=Z^\]i0 r $$gZh^oZ l^Yi] ^[ cZZYZY ^[Vg\jbZcih#l^Yi] 2 '*+ p >bV\ZHZi6ci^Va^Vh^c\]^hi>bV\Z!ºdcº0 >bV\ZGZh^oZ]^hi>bV\Z!Vg\jbZcih#l^Yi]!Vg\jbZcih#]Z^\]i!º]^\]ZhiFjVa^inº0 r0 $$gZijgc ^bV\Z gZijgc ]^hi>bV\Z0 1$X[hXg^ei3 1$X[[jcXi^dc3 1""" 222222222222222222222222222222222222222222222222222222222222222222222 """3 1""" YgVl8dadg=^hid\gVb """3 1X[[jcXi^dc cVbZ2ºYgVl8dadg=^hid\gVbº VXXZhh2ºeg^kViZº gZijgcineZ2ºVcnº djieji2º[VahZº ]^ci2º> YgVl V Xdadg ]^hid\gVb ^bV\Zº3 1X[Vg\jbZci cVbZ2º]^hid\gVbº gZfj^gZY2ºnZhº ]^ci2º]^hid\gVbº $3
Using Java Class Objects
C`jk`e^ -/%*
(continued)
1X[Vg\jbZci cVbZ2ºl^Yi]º gZfj^gZY2ºnZhº YZ[Vjai2º'*+º ineZ2ºcjbZg^Xº ]^ci2ºl^Yi] d[ ^bV\Z id XgZViZº $3 1X[Vg\jbZci cVbZ2º]Z^\]iº gZfj^gZY2ºnZhº YZ[Vjai2º&'%º ineZ2ºcjbZg^Xº ]^ci2º]Z^\]i d[ ^bV\Z id XgZViZº $3 1X[hXg^ei3 kVg ^ 2 ¹º0 kVg ^^ 2 ¹º0 kVg Xdadg 2 ¹º0 $$XgZViZ ^bV\Z kVg ]^hi>bV\Z 2 ^bV\ZCZl¹º!'*+!Vg\jbZcih#]Z^\]i!ºVg\Wº0 $$hZi YgVl^c\ igVcheVgZXZcn >bV\ZHZi9gVl^c\IgVcheVgZcXn]^hi>bV\Z!++0 $$adde i]gj Xdadg W^ch g"\"W [dg^2&0^ AI: (0 ^2^ & p $$hZi Xdadg WVhZY dc W^c ^[ ^ 22 & p$$gZY >bV\ZHZi9gVl^c\8dadg]^hi>bV\Z!ºgZYº0 Xdadg 2 ¹gº0 r ZahZ ^[ ^22' p$$\gZZc >bV\ZHZi9gVl^c\8dadg]^hi>bV\Z!º\gZZcº0 Xdadg 2 ¹\º0 r ZahZ ^[ ^22( p$$WajZ >bV\ZHZi9gVl^c\8dadg]^hi>bV\Z!ºWajZº0 Xdadg 2 ¹Wº0 r $$adde i]gj Vaa W^ch ^c Xdadg [dg^^2&0^^ AI: '*+0 ^^2^^ & p $$hZi bVm ]Z^\]i WVhZY dc i]Z bVm h^oZ [djcY ^c VggVn a^cZ=Z^\]i 2 Vg\jbZcih#]Z^\]i"Vg\jbZcih#]^hid\gVbPXdadgR#]^hid\gVbP^^R$ VggVnBVmVg\jbZcih#]^hid\gVbPXdadgR#]^hid\gVb Vg\jbZcih#]Z^\]i0 $$YgVl a^cZ ^bV\Z9gVlA^cZ]^hi>bV\Z!^^"&!Vg\jbZcih#]Z^\]i!^^"&!a^cZ=Z^\]i0 r r $$gZh^oZ l^Yi] ^[ cZZYZY ^[Vg\jbZcih#l^Yi] 2 '*+ p >bV\ZHZi6ci^Va^Vh^c\]^hi>bV\Z!ºdcº0 >bV\ZGZh^oZ]^hi>bV\Z!Vg\jbZcih#l^Yi]!Vg\jbZcih#]Z^\]i!º]^\]ZhiFjVa^inº0 r0 $$gZijgc ^bV\Z gZijgc ]^hi>bV\Z0 1$X[hXg^ei3 1$X[[jcXi^dc3 1""" 222222222222222222222222222222222222222222222222222222222222222222222 """3 1""" XgZViZ=^hid\gVb=daYZgHigjXi """3 1X[[jcXi^dc cVbZ2ºXgZViZ=^hid\gVb=daYZgHigjXiº VXXZhh2ºeg^kViZº gZijgcineZ2ºhigjXiº djieji2º[VahZº ]^ci2º> XgZViZ V ]^hid\gVb VggVnº3 1X[hXg^ei3 kVg ]daYZgHigjXi 2 higjXiCZl0 ]daYZgHigjXi#]^hid\gVb 2 VggVnCZl&0 ]daYZgHigjXi#bZVc 2 ¹º0 ]daYZgHigjXi#hiVcYVgYYZk^Vi^dc 2 ¹º0 ]daYZgHigjXi#b^c 2 ¹º0 ]daYZgHigjXi#bVm 2 ¹º0 gZijgc ]daYZgHigjXi0 1$X[hXg^ei3
513
514
CHAPTER
68
C`jk`e^ -/%*
Extending ColdFusion with Java
(continued)
1$X[[jcXi^dc3 1""" 222222222222222222222222222222222222222222222222222222222222222222222 """3 1""" \Zi=^hid\gVbHiVi^hi^Xh """3 1X[[jcXi^dc cVbZ2º\Zi=^hid\gVbHiVi^hi^Xhº VXXZhh2ºeg^kViZº djieji2º[VahZº3 1X[Vg\jbZci cVbZ2ºkVajZhº gZfj^gZY2ºnZhº3 1X[hXg^ei3 kVg gZijgcHigjXi 2 higjXiCZl0 $$kVg ]^hi6ggVn 2 Vg\jbZcih#kVajZh0 kVg CjbKVajZh 2 %0 kVg m 2 %0 kVg hjbm 2 %0 kVg ^2%0 $$b^c gZijgcHigjXi#b^c 2 VggVnB^cVg\jbZcih#kVajZh0 $$bVm gZijgcHigjXi#bVm 2 VggVnBVmVg\jbZcih#kVajZh0 ]^hiAZc\i] 2 VggVnAZcVg\jbZcih#kVajZh0 m 2 VggVn6k\Vg\jbZcih#kVajZh0 [dg ^2&0 ^ AI: ]^hiAZc\i]0 ^2^ & p hjbm 2 hjbm Vg\jbZcih#kVajZhP^R " m Vg\jbZcih#kVajZhP^R " m0 r0 $$bZVc gZijgcHigjXi#bZVc 2 m0 $$H9 gZijgcHigjXi#hiVcYVgYYZk^Vi^dc 2 hfghjbm$]^hiAZc\i]0 gZijgc gZijgcHigjXi0 1$X[hXg^ei3 1$X[[jcXi^dc3 1$X[XdbedcZci3
We will not go into depth about how this CFC works because we are assuming that you are familiar enough with Java to look up each class and method requested from the JAI library. One thing to note is how cleanly ColdFusion allows you to integrate with Java components and libraries using either standard CFML or CFScript. Now let us use 8;>B6C;$a^W folder, which should be located within your Web server’s (or virtual Web server’s) document root folder.
Using Tag Libraries
EFK
C;# k_\e X jlY]fc[\i ZXcc\[ a^W% 8cjf# Xj ]Xi Xj :fc[=lj`fe `j ZfeZ\ie\[# pfl ZXe gcXZ\ k_\ ]fc[\i `e fk_\i cfZXk`fej Xj n\cc# Ylk `kËj ZljkfdXip kf gcXZ\ kX^ c`YiXip Ôc\j `e L:7">C;$a^W% K_\ kX^ c`YiXip dXp Y\ \og\Zk`e^ `k `ek\ieXccp%
In most cases, that’s all you need to do to install the library. It’s also possible that additional #_Vg files, #egdeZgin files, or other files may need to exist in order for the tag library to work properly; the tag library’s documentation should make all this clear to you. EFK
C;$a^W ]fc[\i `] gifdgk\[% K_\ `ejkXcc\i gifYXYcp \og\Zkj pfl kf Y\ lj`e^ k_\ c`YiXip n`k_ AJG gX^\j iXk_\i k_Xe :fc[=lj`fe# jf `kËj gfjj`Yc\ k_Xk pflËcc e\\[ kf dfm\ k_\ #_Vg Xe[&fi #iaY Ôc\j X]k\i `ejkXccXk`fe%
@dgfik`e^ k_\ C`YiXip n`k_ 1XÄbedgi3 Now that the tag library files have been placed into their correct location, you should be able to import the library with the 1XÄbedgi3 tag, using the syntax described in Table 68.4. As of ColdFusion 9, you can also use the ^bedgi statement in CFScript. KXYc\ -/%+ 1XÄbedgi3 Tag Syntax for Importing Tag Libraries ATTRIBUTE
DESCRIPTION
I67
The location of the tag library file(s). If the tag library came with a separate #iaY file, provide that location. Otherwise, use the path to the #_Vg file. Assuming that you placed the files in the L:7">C;$a^W folder, you would use I672 ¹L:7">C;$ a^W$iV\a^W#iaYº or I672ºL:7">C;$a^W$iV\a^W#_Vgº, replacing the iV\a^W part with the actual file names in question.
EG:;>M
A prefix to use for referring to the tags in the tag library. For the remainder of the current ColdFusion page, you will be able to refer to the tags in the form 1egZÄm/iV\cVbZ3, where the egZÄm is the value you supply here.
K@G
Pfl ZXe gifm`[\ Xep `[\ek`Ô\i pfl nXek Xj k_\ EG:;>M# Xj cfe^ Xj `k `j efk X i\j\im\[ nfi[# Ylk k_\i\ n`cc ljlXccp Y\ X ZljkfdXip gi\Ôo ]fi k_\ kX^ c`YiXip pflËi\ lj`e^ f]k\e k_\ jXd\ gi\Ôo lj\[ `e k_\ [fZld\ekXk`fe fi \oXdgc\j k_Xk Zfd\ n`k_ k_\ c`YiXip % @ i\Zfdd\e[ k_Xk pfl lj\ k_\ ZljkfdXip gi\Ôo n_\e\m\i gfjj`Yc\% EFK
ciZ\gVi^c\8;BA#X[b 6ji]dg/ CViZ LZ^hh CBL EjgedhZ/ H]dlh ]dl 8daY;jh^dc eV\Zh! ?HE eV\Zh! VcY HZgkaZih XVc eVgi^X^eViZ ^c i]Z hVbZ eV\Z gZfjZhi """3 1]iba3 1]ZVY31i^iaZ38daY;jh^dc! ?HE! VcY HZgkaZi >ciZ\gVi^dc1$i^iaZ31$]ZVY3 1WdYn3 1]'36 ;g^ZcYan 8dckZghVi^dc1$]'3 1""" HZi V kVg^VWaZ ^c i]Z G:FJ:HI hXdeZ# """3 1""" I]^h kVg^VWaZ l^aa WZ k^h^WaZ id Vcn ^cXajYZY ?HE VcY HZgkaZi eV\Zh """3 1X[hZi G:FJ:HI#CVbZ 2 ¹CViZº3 1""" 9^heaVn V h^beaZ bZhhV\Z! jh^c\ cdgbVa 8daY;jh^dc hnciVm """3 1X[djieji3 1W3=Zaad! G:FJ:HI#CVbZ# I]^h ^h 8daY;jh^dc iVa`^c\#1$W31Wg3 Ndj VcY gZVaan > ]VkZ hdbZ ^hhjZh i]Vi lZ cZZY id ldg` dji! Ydc¼i lZ41Wg3 D] lV^i! 9g# ?HE lVcih id ]VkZ V ldgY l^i] ndj#1Wg3 1$X[djieji3 1""" >cXajYZ V ?HE eV\Z """3 1X[hZi ciZ\gVi^c\?HE#_heº3
Integrating with Java Servlets and JSP Pages
C`jk`e^ -/%/
(continued)
1""" 6cdi]Zg 8daY;jh^dc bZhhV\Z """3 1X[djieji3 1e31W3Jb! ]^! i]^h ^h 8daY;jh^dc V\V^c#1$W31Wg3 L]Vi ]VeeZcZY! Y^Y 9g# ?HE [dg\Zi l]Vi h]Z lVh \d^c\ id hVn V\V^c4 I]dhZ ?HEh iZcY id ÅV`Z dji [gdb i^bZ id i^bZ# >¼aa eVhh ndj dkZg id >ciZ\gVi^c\HZgkaZi cdl# 6 ldgY d[ lVgc^c\/ ]Z¼h V W^i### higZhhZY dji aViZan# > ]deZ ndj bV`Z ^i WVX` ^c dcZ e^ZXZ###1Wg3 1$X[djieji3 1""" >cXajYZ V ?VkV HZgkaZi """3 1X[hZi ciZ\gVi^c\HZgkaZiº3 1""" H]dl i]Vi G:FJ:HI kVg^VWaZ XVc WZ X]Vc\ZY Wn ?HE eV\Zh dg HZgkaZih """3 1X[djieji3 1e31W3=^! i]^h ^h 8daY;jh^dc dcXZ V\V^c#1$W31Wg3 LZaa! ^i¼h hjgZ WZZc c^XZ iVa`^c\ id ndj! G:FJ:HI#CVbZ#1Wg3 =VkZ V c^XZ V[iZgcddc1Wg3 1$X[djieji3 1$WdYn3 1$]iba3
Listing 68.9 shows the code for the JSP page that is included by the ColdFusion page in Listing 68.8. Note that it is able to use standard JSP-style gZfjZhi#\Zi6iig^WjiZ syntax to refer to the value that ColdFusion calls G:FJ:HI#CVbZ. C`jk`e^ -/%0
>ciZ\gVi^c\?HE#_he —JSP
Page Included by Listing 68.8
1"" ;^aZcVbZ/ >ciZ\gVi^c\?HE#_he 6ji]dg/ CViZ LZ^hh CBL EjgedhZ/ 9ZbdchigViZh kVg^VWaZ"h]Vg^c\ WZilZZc Zck^gdcbZcih ""3
1"" I]Z G:FJ:HI kVg^VWaZ i]Vi lVh hZi ^c i]Z 8daY;jh^dc eV\Z ""3 1"" ^h VkV^aVWaZ ]ZgZ Vh Vc Viig^WjiZ d[ i]Z ?HE ¹gZfjZhiº dW_ZXi ""3 1e3 1W3=^ i]ZgZ 12 gZfjZhi#\Zi6iig^WjiZ¹cVbZº 3# 9g# ?HE ]ZgZ### ]dl nV Yd^c\41$W31Wg3 XdbeaZiZan [dg\di l]Vi > lVh \d^c\ id hVn#1Wg3 >¼¼b \d^c\ id eVhh ndj WVX` id 8daY;jh^dc cdl# EZVXZ dji! YjYZ1Wg3
EFK
Remove Selected IP Addresses for Exposed Services area. You are now ready to make calls to the ESL from the IP addresses you just specified using the credentials you specified immediately before that.
DXb`e^ :Xccj kf k_\ <JC Because the ColdFusion 9 ESL is implemented as a collection of Web services, any technology capable of consuming Web services can make use of the ColdFusion 9 ESL.
Making Calls to the ESL
:Xcc`e^ k_\ <JC ]ifd :fc[=lj`fe Although the ESL was developed to enable ColdFusion functionality to be called from other technologies without a need to write any ColdFusion code, it can be called from ColdFusion as well— and for purposes of learning how to call the ESL, making calls from ColdFusion is a great way to start. If you view the WSDL for ^bV\Z#X[X in the 8;>9:QhZgk^XZh directory, you will see that one of the operations of Image Service is 9:$hZgk^XZh$^bV\Z#X[X4lhYaº bZi]dY2ºbedgi i]Z gZfj^gZY BMBA a^WgVg^Zh# ^bedgi bm#ZkZcih#;aZm:kZci0 ^bedgi XdaY[jh^dc#hZgk^XZ#ZkZcih#0 $$ EZg[dgb ^c^i^Va^oVi^dc# egdiZXiZY [jcXi^dc ^c^i/kd^Y p $ 8Vaa i]Z ZmZXjiZ bZi]dY d[ i]Z >bV\Z egdmn XaVhh ^chiVcXZ# I]^h XVjhZh V XVaa id i]Z deZgVi^dc d[ i]Z >bV\Z LZW HZgk^XZ i]Vi ^h heZX^ÄZY ^c i]Z VXi^dc Viig^WjiZ d[ i]Z >bV\Z egdmn XaVhh ^chiVcXZ l]^X]! ^c i]^h XVhZ! ^h bV\Z#ZmZXjiZ0 r $$ L]Zc i]Z XVaa id bV\Z=Z^\]i#iZmi 2 ZkZci#gZhjai Vh Hig^c\0 r RR3 1$[m/HXg^ei3 1[m/9ZXaVgVi^dch3 1"" 8gZViZ Vc ^chiVcXZ d[ i]Z 8dcÄ\ egdmn XaVhh VcY \^kZ ^i i]Z adXVi^dc d[ i]Z 8daY;jh^dc . HZgkZg VcY i]Z hZgk^XZjhZgcVbZ VcY hZgk^XZeVhhldgY kVajZh# ""3 1X[/8dcÄ\ ^Y2ºX[:HA8dcÄ\º X[HZgkZg2ºadXVa]dhiº hZgk^XZJhZgCVbZ2ºgZbdiZjhZgº hZgk^XZEVhhldgY2ºgZbdiZjhZgeVhhldgYº$3 1"" 8gZViZ Vc ^chiVcXZ d[ i]Z >bV\Z egdmn XaVhh VcY \^kZ ^i i]Z i]Z bZi]dY d[ i]Z >bV\ZHZgk^XZ id XVaa l]^X]! ^c i]^h XVhZ! ^h bV\Z ^Y2ºX[:HA>bV\Zº VXi^dc2º9:QhZgk^XZh directory of the ColdFusion 9 Web root can be viewed as extending the functionality of the ColdFusion 9 ESL. However, to truly extend the functionality of the ColdFusion 9 ESL, you need to take advantage of its security infrastructure—and fortunately, the architecture of the ColdFusion 9 ESL makes this easy: simply extend WVhZ#X[X and call its ^h6aadlZY and ^h6aadlZY>E methods. The WVhZ#X[X CFC also provides a number of other methods you may find helpful when extending the functionality of the ColdFusion 9 ESL. It’s easy to find out more about WVhZ#X[X (or, for that matter, any other CFC, including the other CFCs that are part of the ColdFusion 9 ESL): just use ColdFusion 9’s CFC Explorer (see “More on Using ColdFusion Components” in Chapter 11, “The Basics of Structured Development,” in Volume 1). If you directly request WVhZ#X[X in your browser, you will see its documentation, including information about its methods (WVhZ#X[X doesn’t have any properties but if it did, you would see information about those as well). The screen should look like Figure 69.9. =`^li\ -0%0 Viewing WVhZ#X[X with ColdFusion 9’s CFC Explorer.
Extending the ESL
Document Service doesn’t provide the capability to generate a document from a #YdX or #eei file, but the 1X[YdXjbZci3 tag does have that capability—so it’s a prime area in which to extend the functionality of the ColdFusion 9 ESL. Listing 69.5 shows sample code that extends the ColdFusion 9 ESL to generate documents from #YdX and #eei files. C`jk`e^ -0%, YdXjbZci[gdbhgXÄaZ#X[XÇEVg\jbZcih#hZgk^XZjhZgcVbZ! adXVa#eVgZciHZgk^XZ3 1""" HZi i]Z iZbedgVgn ÄaZ eVi] [dg i]Z E9;# """3 1X[hZi adXVa#iZbe;^aZEVi] 2 Xk\nXp @ejkXeZ\
<m\ek
<m\ek >Xk\nXp @ejkXeZ\
@D
<m\ek
<m\ek
JDJ
<m\ek
<m\ek
J8G&Xk\nXp @ejkXeZ\
:=<m\ek
:=<m\ek
:=<m\ek
:=<m\ek
:=<m\ek
:=<m\ek
<M<EK >8KB6cZiejW$lllgddi$\ViZlVnX]VeiZg$\VaaZgn
Table 70.1 lists a number of other configuration file attributes you can set. After you’ve edited the directory path, save the file. EFK
[ i]Z i]jbWcV^a YdZh cdi Zm^hi """3 1XÄ[ cdi ;^aZ:m^hihI]jbWEVi]3 1""" >ckd`Z djg ^bV\Z"gZh^o^c\ [jcXi^dc """3 1XÄbV\Z VXi^dc2ºgZh^oZº ]Z^\]i 2 ¹'*º hdjgXZ2ºEI block and then used the HZcY86I>DC scope. Then you can dump the contents of the scope and see any information about what you are tracking.
567
568
CHAPTER
70
Working with Gateways
Another major debugging approach that should always be part of any development—but especially with CFCs and CFML applications that use gateways—is creating unit tests. You can easily do this by creating simple CFML pages that use the HZcYXk\nXpj Although ColdFusion 9 comes with a number of useful gateways, what happens when you want to connect to something that’s not covered by one of the gateways provided? What if you want to connect to your MQ Series server, or SAP via the BAPI messaging interface? The answer is to create your own gateway. Writing ColdFusion 9 gateways is a fairly straightforward task, but gateways are developed completely in Java and you’ll need to have a solid understanding of Java to write your own event gateways.
:fc[=lj`fe <m\ek >Xk\nXp 8iZ_`k\Zkli\ Event gateways listen for events and pass them to ColdFusion for handling by an application’s listener CFC. The gateway does this by implementing the 8daY;jh^dc#ZkZci\ViZlVn#C< , HIDEE>C< , HIDEE:9, ;6>A:9.
kd^Y
hiVgi
Starts the event gateway. ColdFusion calls this method on startup.
kd^Y
hide
This method stops the event gateway and kills any threads and cleans up any resources it was using.
kd^Y
gZhiVgi
Restarts a running event gateway.
Hig^c\
dji\d^c\BZhhV\Z 8;:kZci X[bZh\
Sends a message from the gateway to a resource.
instance.
>Xk\nXp J\im`Z\j :cXjj To interact with the ColdFusion event gateway services, you used the Gateway class 8daY;jh^dc# ZkZci\ViZlVn#9
8;:kZci constructor that expects a string, which is the \ViZlVn>9
kd^Y
hZiB , HBH, or :BV^a
kd^Y
hZi9ViVBVe YViV
Adds the gateway-specific data, including any message contents, as a Java Map to the 8;:kZci object
kd^Y
hZiDg^\^cVidg>9Hig^c\ ^Y
Sets the originator of an incoming message.
kd^Y
hZi8;8EVi]Hig^c\ eVi] Specifies the listener CFC that will process
this event kd^Y
hZi8;8BZi]dYHig^c\ bZi]dY
Sets the name of the CFC method that should process an incoming message
kd^Y
hZi8;8I^bZdjiHig^c\ hZXdcYh
Sets the timeout, in seconds, during which the listener CFC must process the event request before ColdFusion gateway services terminates the request and logs an error in the Veea^XVi^dc#ad\ file
Hig^c\
\Zi9
Identifies the originator of an incoming message
Hig^c\
\Zi8;8EVi]
Gets the path to the listener CFC that processes this message
Hig^c\
\Zi8;8BZi]dY
Gets the name of the CFC method that processes the message
Hig^c\
\Zi9
Identifies the event gateway instance, as specified in the ColdFusion Administrator
571
572
CHAPTER
70
Working with Gateways
>Xk\nXp ?\cg\i :cXjj The C;QX[jh^dcQ\ViZlVnQ%
When you’re sure that your #_Vg files are in the right place, go to the ColdFusion Administrator and click on Event Gateway and then on Gateway Types. The first field is the event Type Name. Enter EDE( Gateway Instances creation screen, so for this example, use IZhi d[ Xk\nXp @ejkXeZ\ Inside the ColdFusion Administrator you will need to go to the Event Gateway Instances properties page and add a new gateway instance. For this application, we called our gateway =ZaeYZh`, we called our gateway CFC ^b#X[X, and we called our configuration file ]ZaeYZh`#X[\. There are two key details in creating your new instance: the CFC that will handle all of your requests and the configuration file itself. Make sure you get these both right and you will be set. K@G
8k k_`j gf`ek `k nflc[ Y\ n`j\ kf k\jk pfli e\n ^Xk\nXp% Aldg `ekf k_\ :fc[=lj`fe 8[d`e`jkiXkfi Xe[ dXb\ jli\ k_Xk `k jkXikj%
585
586
CHAPTER
71
Integrating with SMS and IM
:i\Xk`e^ Pfli =`ijk @D 8ggc`ZXk`fe Now that you have your gateway set up, it would be great to test it and make sure that it works. To do so we will use a simple “Hello World” application. EFK
cXdb^c\BZhhV\Z function in your ^b#X[X to look like Listing 71.2. C`jk`e^ .(%)
^b#X[X —Modifying
the dc>cXdb^c\BZhhV\Z Function
1X[[jcXi^dc cVbZ2ºdc>cXdb^c\BZhhV\Zº3 1X[Vg\jbZci cVbZ2º8;:kZciº ineZ2ºhigjXiº gZfj^gZY2ºN:Hº3 1""" 9 id i]Z^g WjYYn a^hi#º3 1X[Vg\jbZci cVbZ2º8;:kZciº ineZ2ºhigjXiº gZfj^gZY2ºN:Hº3 1""" GZijgc i]Z VXi^dc YZX^h^dc# """3 1X[hZi gZiKVajZ 2 higjXiCZl3 1X[hZi gZiKVajZ#XdbbVcY 2 ¹VXXZeiº3
C`jk`e^ .(%*
(continued)
1X[hZi gZiKVajZ#7jYYn>9 2 8;:kZci#96I6#H:C9:G3 1X[hZi gZiKVajZ#GZVhdc 2 ¹7ZXVjhZ lZ VgZ c^XZº3 1X[gZijgc gZiKVajZ3 1$X[[jcXi^dc3
Lj\i JkXklj DXeX^\d\ek Inside our gateway CFC you may have noticed a method called dc7jYYnHiVijh. This is called when one of the members of our buddy list changes their status. We will cache this information in the 6EEA>86I>DC scope, so that we can use this in the rest of our application. If we add the following code into our dc7jYYnHiVijh function we will have the status of all of our buddies available to the rest of the application: 1X[[jcXi^dc cVbZ2ºdc7jYYnHiVijhº ]^ci2ºEgZhZcXZ hiVijh bZhhV\Zh [gdb di]Zg jhZgh#º3 1X[Vg\jbZci cVbZ2º8;:kZciº ineZ2ºhigjXiº gZfj^gZY2ºN:Hº3 1XÅdX` hXdeZ2º6EEA>86I>DCº i^bZdji2º&%º ineZ2º:M8AJH>K:º3 1X[hXg^ei3 $$ 8gZViZ i]Z hiVijh higjXijgZh ^[ i]Zn Ydc¼i Zm^hi# ^[ CDI HigjXi@Zn:m^hih6EEA>86I>DC! ¹WjYYnHiVijhº p 6EEA>86I>DC#WjYYnHiVijh2HigjXiCZl0 r
587
588
CHAPTER
71
Integrating with SMS and IM
^[ CDI HigjXi@Zn:m^hih6EEA>86I>DC#WjYYnHiVijh! 8;:kZci#9ViV#7J99NC6B: p 6EEA>86I>DC#WjYYnHiVijhP8;:kZci#9ViV# 7J99NC6B:R2HigjXiCZl0 r $$ HVkZ i]Z WjYYn hiVijh VcY i^bZhiVbe# 6EEA>86I>DC#WjYYnHiVijhP8;:kZci#9ViV#7J99NC6B:R#hiVijh 2 8;:kZci#9ViV#7J99NI6IJH0 6EEA>86I>DC#WjYYnHiVijhP8;:kZci#9ViV#7J99NC6B:R#i^bZHiVbe 2 8;:kZci#9ViV# I>B:HI6BE0 1$X[hXg^ei3 1$XÅdX`3 1$X[[jcXi^dc3
You will notice that we have put a 1XÅdX`3 around this code. This is just in case multiple users change their status at exactly the same time. We don’t want to overwrite one change with the other.
K_\ @D >Xk\nXp ?\cg\i As with all gateways, there is a helper class that carries out additional tasks that are specific to that gateway type. In the case of IM gateways there are four main areas of responsibility that our helper takes care of.
9l[[p C`jk DXeX^\d\ek One of the first things we want our application to do when it starts up is to check the status of our helpdesk staff. Typically all of our helpdesk staff will already be buddies in our application but it never hurts to check. Now our application is starting to grow, it is time to build an 6eea^XVi^dc#X[X file into our application. If you haven’t already got one, create an 6eea^XVi^dc#X[X file in your test directory. In our 6eea^XVi^dc#X[X (Listing 71.4), we will add some code that checks our list of users against the buddy list of the IM Gateway and requests authorization to add those users who are not buddies to the list when our application starts using the dc6eea^XVi^dcHiVgi function. To do this we need the VYY7jYYn helper function. EFK
86I>DC! ¹WjYYnHiVijhº p 6EEA>86I>DC#WjYYnHiVijh2HigjXiCZl0 r ^[ CDI HigjXi@Zn:m^hih6EEA>86I>DC#WjYYnHiVijh! V7jYYnA^hiP^R p 6EEA>86I>DC#WjYYnHiVijhPV7jYYnA^hiP^RR2HigjXiCZl0 r $$\Zi i]Z hiVijh [dg i]^h WjYYn hiVijh 2 ]ZaeZg#\Zi7jYYn>c[dV7jYYnA^hiP^R0 $$ÄcY i]Z cdYZ ^c i]Z VggVn i]Vi XdciV^ch i]Z YViV i]Vi lZ cZZY [dg_2&0_ aiZ VggVnAZchiVijh0_2_ & p ^[hiVijhP_R#7jYYnA^hiIneZ Zf ¹7J99NTA>HIº p $$ hVkZ i]Z hiVijh YViV 6EEA>86I>DC#WjYYnHiVijhPV7jYYnA^hiP^RR#hiVijh 2 hiVijhP_R#7J99NHI6IJH0 6EEA>86I>DC#WjYYnHiVijhPV7jYYnA^hiP^RR#i^bZHiVbe 2 hiVijhP_R# 7J99NHI6IJHI>B:0 r r r 1$X[hXg^ei3
In our application we abstracted this functionality into its own function in the 6eea^XVi^dc#X[X file so that we can reuse it elsewhere if needed. We now know enough information that we can go and build an application that takes helpdesk requests and IMs them to an available support staff member. This is done in ^cYZm#X[b#
589
590
CHAPTER
71
Integrating with SMS and IM
>Xk\nXp JkXklj DXeX^\d\ek It would be nice to add some more functionality to our application so that the users in our organization can see at a glance whether their helpdesk staff are busy or not, but to protect our helpdesk staff, we are not going to publish their IM details directly. Instead, we are going to integrate their status into that of our gateway. The virtual helpdesk should reflect whether the agents are busy or free. The gateway helper has a method, hZiHiVijh, that we will be using to very simply show our busy/free status. We will loop over the application scope cache of our agents’ status and use this to set the gateway’s presence status to reflect our helpdesk team. In your ^b#X[X modify the dc7jYYnHiVijh function to include the following code: 1XÅdde XdaaZXi^dc2º6eea^XVi^dc#7jYYnHiVijhº ^iZb2º`Znº3 1XÄ[ CDI HigjXi@Zn:m^hihhiHiVijh! 6EEA>86I>DC#WjYYnHiVijhP`ZnR#HiVijh3 1X[hZi hiHiVijhP6EEA>86I>DC#WjYYnHiVijhP`ZnR#HiVijhR 2 higjXiCZl3 1$XÄ[3 1X[hZi hiHiVijhP6EEA>86I>DC#WjYYnHiVijhP`ZnR#HiVijhRP`ZnR 2 igjZ3 1$XÅdde3 1""" cdl ldg` dji l]Vi hiVijh id eji jh ^c """3 1XÄ[ higjXi@Zn:m^hihhiHiVijh!ºDCA>C:º3 1X[hZi cZlhiVijh 2 ¹DCA>C:º3 1X[ZahZ^[ higjXi@Zn:m^hihhiHiVijh!º6L6Nº3 1X[hZi cZlhiVijh 2 ¹6L6Nº3 1X[ZahZ3 1X[hZi cZlhiVijh 2 ¹C6º3 1$XÄ[3 1X[hZi ]ZaeZg 2 \ZiXk\nXp :feÔ^liXk`fe Beyond the normal helper methods, there are a few that provide statistics on the gateway itself: N
N
9 ^h ¹ iVh`>90 WgZV`0 XVhZ ¹6º/ XVhZ ¹6hh^\cº/ hiV[[9ZiV^ah 2\ZiHiV[[9ZiV^ah^b^Y2Vg\jbZcih#8;:kZci#YViV#H:C9:G0 iVh`>9 2 Vhh^\cIVh`hiV[[9ZiV^ah#jhZg^Y0 ^[aZciVh`>9 Zf % p
Creating Interactive Applications
C`jk`e^ .(%,
(continued)
XVhZ XVhZ XVhZ
XVhZ XVhZ XVhZ
bh\ 2 ¹i]ZgZ VgZ cd jcVhh^\cZY iVh`h Vi i]^h i^bZº0 r ZahZ p bh\ 2 ¹Ndj ]VkZ WZZc Vhh^\cZY V cZl iVh`#º0 r WgZV`0 ¹Gº/ ¹gZ_ZXiº/ ¹YZcnº/ bh\ 2 ¹I]^h iVh` ]Vh WZZc gZ_ZXiZY! ^i l^aa WZ gZijgcZY id i]Z fjZjZ#º X]g&(00 bh\ 2 bh\ ¹Ndj XVc ValVnh bVg` ndjghZa[ Vh »6lVn¼ VcY i]Z ]ZaeYZh` hnhiZb l^aa cdi VjidbVi^XVaan VaZgi ndj id cZl iVh`hº0 WgZV`0 ¹8º/ ¹8dbeaZiZº/ ¹8adhZº/ $$ ldg` dji l]d i]^h jhZg ^h VcY \Zi i]Z^g XjggZci a^hi d[ iVh`h hiV[[9ZiV^ah 2\ZiHiV[[9ZiV^ah^b^Y2Vg\jbZcih#8;:kZci#YViV#H:C9:G0 V9ZiV^ah 2 \ZiIVh`9ZiV^ahhiV[[9ZiV^ah#jhZg^Y0 hl^iX]VggVnAZcV9ZiV^ah p XVhZ %/ bh\ 2 ¹Ndj Yd cdi ]VkZ Vcn iVh`h XjggZcian VXi^kZº X]g&(0 WgZV`0 XVhZ &/ XadhZ>hhjZV9ZiV^ahP&R#^Y0 bh\ 2 ¹Ndj ]VkZ bVg`ZY ndjg XjggZcian VXi^kZ iVh` Vh XdbeaZiZ#º V9ZiV^ahP&R#^Y X]g&(0 WgZV`0 YZ[Vjai/ $$ i]^h jhZg ]Vh bdgZ i]Vc dcZ XVhZ $$X]ZX` [dg V cjbWZg V[iZg i]Z `ZnldgY ^[ egZhZci! $$XadhZ i]Vi XVhZ ^[a^hiAZcbZhhV\Z!¼ » \i & VcY ^hCjbZg^XA^hihhjZV9ZiV^ahPi]^hIVh`R#^Y0 bh\ 2 ¹Ndj ]VkZ XadhZY iVh` ¹ i]^hIVh` ¹#º0 r ZahZ p bh\ 2 ¹Ndj ]VkZ bdgZ i]Vc dcZ iVh` deZc Vi egZhZci# EaZVhZ XdcÄgb l]^X] iVh` ndj l^h] id XadhZ#º X]g&(0 [dg^ 2&0^ aiZ VggVnAZcV9ZiV^ah0^2^ & p bh\ 2 bh\ ^ ¹# ¹ V9ZiV^ahP^R#HjW_ZXi X]g&(0 r r r WgZV`0
XVhZ ¹9º/ XVhZ ¹9ZiV^ahº/ hiV[[9ZiV^ah 2\ZiHiV[[9ZiV^ah^b^Y2Vg\jbZcih#8;:kZci#YViV#H:C9:G0 V9ZiV^ah 2 \ZiIVh`9ZiV^ahhiV[[9ZiV^ah#jhZg^Y0 ^[a^hiAZcbZhhV\Z!¼ » \i & VcY ^hCjbZg^XA^hi9 2 Vg\jbZcih#8;:kZci#YViV#H:C9:G0 gZigjcKVa#bZhhV\Z 2 bh\0 gZijgc gZigjcKVa0 1$X[hXg^ei3 1$X[[jcXi^dc3 1$X[XdbedcZci3
As you can see, a lot of code goes into working out what the user actually wants and this is not the most intelligent system out there. If you want to see a useful automated IM system (often called an IM Robot, or bot for short), using your AOL chat client, chat to greenopolis. Greenopolis is a
Understanding SMS
code-driven IM interface, only in Java, not ColdFusion, that gives information and tips on ecofriendly living. ¨ =fi dfi\ `e]fidXk`fe# _Xm\ X cffb Xk k_\ ^Xcc\ip Xk _kkg1&&^Xcc\ip%X`d%Zfd&Yifnj\&Yfkj%
Le[\ijkXe[`e^ JDJ SMS (Short Message Service) is the ability to send and receive short messages or “texts” between cell phones. When you put it like this, it doesn’t sound like such a big deal, but in the 10-odd years since the first SMS message was sent, these small text messages have rapidly grown to be a huge part of the mobile market. In Europe alone, there are in excess of two billion text messages sent every month. Where does ColdFusion fit in here? In most languages, creating an SMS-based application takes a specialized application server and a ton of custom programming. Just as ColdFusion makes it simple to create dynamic Web pages, it makes it easy to create SMS-based applications. What kinds of applications can be built with this new interface to ColdFusion? Well, the possibilities are almost endless. A few that jump to mind include: voting for your favorite character on the latest round of reality TV shows, getting your new password for a Web application, or even monitoring the health of your ColdFusion server. This could be as important to your Web applications as 1X[bV^a3 is today. The gateway in ColdFusion does some amazing things for you when it comes to IM—it is able to keep track of sessions for you. Even though there is not a Web browser as such, it is very helpful to be able to apply the same concepts we use for our Web development to a series of text messages, thus allowing us to take our existing applications and convert them to SMS applications without much code refactoring. Second, the SMS gateway is also able to authenticate the phone itself, so you know which user is using your application. This does not mean that you don’t need to implement some kind of user authentication or verification at some point. I would still like to know that if I lose my phone someone can’t just pick it up and find out my bank balance. The GSM (Global System for Mobile Communications) standard provides for encrypted traffic between the SMSC (Short Message Service Center) and the cell phone. This gives us a secure environment without having to program in security. Lastly, as your application will be leaving the confines of the Internet, you will need a way to get your SMS messages from your ColdFusion server out onto the cell phone network. Nowadays this is not that hard, but it does take some planning. Many people think that they need to have their own SMS gateway and related infrastructure to get this kind of application up and running, and at one time you did. Recently a new protocol called SMPP (Short Message Peer to Peer) allows you to send an SMS message over a TCP/IP network to an SMS gateway server (SMSC), thus saving you the hassle of having your own. You will need an account with a provider that will support SMPP 3.4 over TCP/IP, but we will cover that later on.
595
596
CHAPTER
71
Integrating with SMS and IM
EFK
\kk`e^ Pfli D\jjX^\j Flk The last step in deploying your SMS application is to change your SMS gateway from the test server that you have been using for development to a real gateway that sends real messages to real phones. The first step is to set up an account with a provider of SMPP access to the SMS network. This can be done either with your telecom provider directly or an SMS service provider. There are two main things to think about when you go shopping for an SMSC provider. The first decision you will need to make is if your application will be push only and send only SMS messages or if it will be a two-way application and will allow users to SMS in requests to your application. The main effect here is price; a push-style gateway is very cheap and easy to set up and can be done almost instantly. A two-way application requires some more setup as you will need your own phone number or short code for your users to send their messages to.
Defining SMS Gateways
A good place to start looking for an SMS provider is with the telecom company that provides your existing phone line or cell phone infrastructure. This is primarily due to differential pricing. In some parts of the world it is cheaper to send text messages to other users on the same network as opposed to going across to another carrier’s network. This is really only an introduction and just enough to get you going. If you wish to learn more about the inner workings of SMPP, point your browser to ]iie/$$hbh[dgjb#cZi for full details of the SMPP specification. Figure 71.1 shows the path of your SMS traffic between your ColdFusion gateways and various mobile devices. =`^li\ .(%( The path of your SMS traffic.
JDGG$ K:G&@G
JDJ >Xk\nXp @ejkXeZ\
JDJ >Xk\nXp @ejkXeZ\ :fc[=lj`fe
:Xii`\i JDJ: :\cc G_fe\
K:
JD G G& G$ @G
JDJ >Xk\nXp @ejkXeZ\
N`i\c\jj E\knfib
JDGG$ K:G&@G
G;8 :Xii`\i JDJ:
K\c\g_fe\
;\Ôe`e^ JDJ >Xk\nXpj Like our IM application, before you can actually use it or even begin testing it, you will need a configuration file and a stub CFC and you will have to create a gateway instance (Listing 71.6). The SMS gateway is fairly straightforward in that it has only one method that needs to be exposed, the dc>cXdb^c\BZhhV\Z method that listens for inbound SMS messages. C`jk`e^ .(%- hbhThijW#X[X —Empty SMS Gateway CFC 1X[XdbedcZci3 1X[[jcXi^dc cVbZ2ºdc>cXdb^c\BZhhV\Zº ]^ci2ºHiVcYVgY bZhhV\Z [gdb HBH jhZghº3 1X[Vg\jbZci cVbZ2º8;:kZciº ineZ2ºhigjXiº gZfj^gZY2ºN:Hº3 1$X[[jcXi^dc3 1$X[XdbedcZci3
To keep things relatively simple we will be using the inbuilt test SMS server, so go and grab the default configuration file from your ColdFusion installation. It is found in the X[TgddiQL:7">C;Q
597
598
CHAPTER
71
Integrating with SMS and IM
X[jh^dcQ\ViZlVnQXdcÄ\ directory on J2EE configurations, and in the X[TgddiQ\ViZlVnQXdcÄ\ directory on standard server configurations.
Unlike the IM configuration file there are a lot of different settings that you will need for your configuration file, the most basic of which are the connection details to the SMSC server. These are the basic settings but you will want to copy the default settings from within your ColdFusion installation as there are many options that you can tweak if needed. You will find the default configuration file in the X[TgddiQL:7">C;QX[jh^dcQ\ViZlVnQXdcÄ\ directory on J2EE configurations, and in the X[TgddiQ\ViZlVnQXdcÄ\ directory on standard server configurations. Here’s an example: HBH8 hZgkZg YZiV^ah ^e"VYYgZhh2&',#%#%#& edgi2,.%& hnhiZb"^Y2X[ eVhhldgY2X[ HdjgXZ VYYgZhh [dg i]^h Xa^Zci hdjgXZ"idc2& hdjgXZ"ce^2& hdjgXZ"VYYgZhh2***&'&' I]Z VYYgZhh gVc\Z i]^h hbee Xa^Zci l^aa hZgkZ \e\iXk`e^ JDJ D\jjX^\j Once you have defined your gateway, it is time to write your first SMS application and start sending some text messages. For the time being, let’s put this in a test file: 1X[hXg^ei3 bh\ 2 higjXiCZl0 bh\#XdbbVcY 2 ¹hjWb^iº0 bh\#YZhi6YYgZhh 2 ¹***&'()º0 bh\#h]dgiBZhhV\Z 2 ¹=^ [gdb 8daY;jh^dcº0 gZi 2 hZcY90 bh\#h]dgiBZhhV\Z 2 Ig^bVg\jbZcih#8;:kZci#YViV#bZhhV\Z0 gZijgc bh\0 1$X[hXg^ei3 1$X[[jcXi^dc3
While this is quite similar to the IM gateway dc>cXdb^c\BZhhV\Z function, you will notice that there is a very different set of properties exposed to you—in particular the dg^\^cVidg>9, or the phone number from which the message was generated.
<ejli`e^ ;\c`m\ip f] Pfli D\jjX^\j Now that you have sent your message, it would be nice to make sure that your user has received it. This can be done with the SMS protocol, but it does require a little more work. First you will need to make sure that your gateway is configured for synchronous message delivery and that when you call the HZcY9 as it comes back and store it for future reference. Typically this would be in a database somewhere. Next when you submit your message to the gateway you will need to include a GZ\^hiZgZY9Za^kZgn field in the message request. This takes one of three options: N
0: This is the default; do not return any status information.
N
1: Return a receipt if the message is delivered or fails.
N
2: Return a receipt if the message is not delivered before the time out (Validity Period).
The second two options instruct the SMSC to return a message back to our gateway reporting on the status of the message. You will need to recode your dc>cXdb^c\BZhhV\Z method of the gateway CFC to look for these messages and separate them from regular incoming messages. This message is returned in the following format: ¹^Y/>>>>>>>>>> hjW/HHH YakgY/999 hjWb^i YViZ/NNBB99]]bb YdcZ YViZ/NNBB99]]bb hiVi/9999999 Zgg/: IZmi/ ###º
Now that you have the status of the message, you can query your bZhhV\Z>9 database table and make an intelligent decision about what should be done with this message—whether we choose to resend this message or maybe escalate it to another user.
Extending Your Application Even Further
J\jj`fej Xe[ JDJ As with standard ColdFusion, the first time an SMS user sends a message to our gateway ColdFusion generates a session for that user. As the users’ interaction with the server is much more limited than it would be if they were using a browser, this session becomes much more important. It allows us to store and track information about their past interactions with the gateway. For example, in our helpdesk application, if agents asked for a new case to be assigned to them and then asked for the details of their cases, it would be fairly safe to assume that they only really want the details of their latest opened case to be sent to their phone, not the details of every single case. This allows us to reduce the number of keystrokes that users may be required to send to the gateway to get the details that they need. There is nothing fancy that you need to add to your application beyond the normal session code that you would add in a normal ColdFusion application.
cXdb^c\BZhhV\Z method that you will need to modify to get this to work. Let’s see what is needed to get this to work. For starters, let’s reproduce our simple “echo” method. In this example we do not cater to any unknown gateways but we could have quite easily put a default case in our application. The next evolution of this would be to take the incoming message and pass it off to another part of the application that would work out the appropriate response to the incoming message. Modify the dc>cXdb^c\BZhhV\Z function of your hbh#X[X to include the following code: 1X[[jcXi^dc cVbZ2ºdc>cXdb^c\BZhhV\Zº3 1X[Vg\jbZci cVbZ2º8;:kZciº ineZ2ºhigjXiº gZfj^gZY2ºN:Hº3 1"""