You will be redirected in 30 seconds or close now.

ColdFusion Authors: Yakov Fain, Jeremy Geelan, Maureen O'Gara, Nancy Y. Nee, Tad Anderson

Related Topics: ColdFusion

ColdFusion: Article

Connecting CF to LDAP

Connecting CF to LDAP

When I started using ColdFusion, one of the tags that piqued my curiosity most was <CFLDAP>. At the time, I had only a vague idea what LDAP was and when I started to write applications that extended beyond single pages, I realized I needed some kind of authentication. I tried the <CF_LOGIN> tag but wasn't thrilled with the idea of storing usernames and passwords in a table.

At the same time, I was setting up Netscape's Messaging Server. While it can use a local file for user information, it prefers an LDAP directory. I immediately saw the advantage of using the LDAP server for both Messaging Server and my ColdFusion applications. So I set about putting up Netscape's Directory Server.

I quickly learned that LDAP directories are significantly different from SQL databases. An LDAP directory is a specialized database for storing information about people and places. As such, the field names, called attributes, are predefined. Although the actual database structure is fairly flat, the directory itself is treelike. The tree metaphor is used frequently in the LDAP world: branches are where the tree splits, leaves are the terminal entries off a branch.

Populating my LDAP directory proved to be a trial by fire as I learned how to use the <CFLDAP> tag. I used ColdFusion to populate the directory and to maintain synchronization between it and the Oracle database it's based on.


LDAP Basics
LDAP queries differ from SQL queries. For example, search information is passed as parameters. While the format for the query is different, the data usually comes back from the server formatted like an SQL query. I say "usually" because it's possible for a given attribute to have multiple values. These are returned as comma-delimited lists.

LDAP directories use a fixed list of column names called attributes, which are defined in the LDAP specification. In addition to the attributes listed in the Advanced ColdFusion Development book, you can find a more complete list at www3.innosoft.com/ldapworld/rfc1617.txt.

Like <CFQUERY>, <CFLDAP> handles all interactions with the LDAP directory. You'll use it for querying, inserting, updating and deleting information from the directory. ColdFusion does some error-checking, but more advanced functions are simply passed directly to the directory server. You'll have to rely on the directory server logs for detailed information about bad LDAP operations.

Custom CF LDAP Tags
A check of the Developer's Exchange turns up two tags for working with LDAP: LDAP_Group and LDIFToQuery. Of the two, the LDAP_Group has proven the most useful. It allows you to maintain directory groups via ColdFusion, rather than the UNIX commands or the server console.

LDIFToQuery will convert LDAP Directory Interchange Format files into queries. LDIF is generally used for bulk loading and unloading a directory server.

Querying an LDAP Directory
Building a basic query is fairly simple. You'll need to provide the name of your directory server, attributes you want, start and query names. The example below will get and print all the distinguished names (dn) at the United States branch in the University of Michigan's LDAP server:

<cfldap name="orglist" server="ldap.itd.umich.edu" attributes="dn" start="c=US"> <cfoutput query="orglist"> #dn#

The equivalent search in SQL would be:

select dn
from ldap
where c = "US'

Filters, the rough equivalent of SQL's WHERE, can be used to narrow the query. The syntax for filters is a bit tortured. To select, for instance, just the State University of New York entries in the example above, you'd add this:

filter="(o=State University of New York*)"

Implementing more complex filters is an interesting challenge. For instance, if I want all the people whose last names fall between A and D, I'd use a filter like:


In this example, the | ORs the four subfilters, so it'll return everything from A to D. You can combine filters from different attributes and nest them as much as you'd like. The more complex your filter is, the longer it'll take the LDAP server to process. Filter performance is affected by attribute indexing. If you plan to search frequently on a particular attribute, make sure the directory server indexes it.

SCOPEing the Query
The examples above look for entries at the level you specify in the START option. In this case we've been looking at entries that fall immediately below the c=US portion of the directory. If there are entries under lower branches, we won't see them. To get to those entries, we need to use SCOPE.

SCOPE can have one of three values: onelevel, base and subtree. The default, onelevel, will go down the directory exactly one branch. That's why we get the organization entries. Base will return entries only at the base level, which is the same as the start.

Subtree, the most productive of all three, will traverse down all branches under the START option, looking for entries that match your filter. If you're not sure where an entry might be, subtree is the easiest way to find it. Since subtree searches the entire LDAP directory, it can take a little longer.

Sorting Queries
The ability to sort your queries is a bit limited. You can only sort on one field. For instance, to sort by last name add SORT= "sn ASC" to your query. The LDAP server will happily return the list to you, sorted by last name. Because names are stored in the commonname (cn) attribute in a human-readable manner, SORT="cn ASC" will return a list sorted by first name.

Other LDAP Peculiarities
Postal addresses are stored in the postalAddress attribute in an LDAP directory. The individual lines of a postal address are separated by a $. My work address, for instance, would be Plattsburgh SUNY$Computing Support$Feinberg Library$Plattsburgh, NY 12901. You could use ListToArray or a <CFLOOP> to properly output the list. The example below will print an address properly:

<cfif len(postaladdress) gt 0>
<cfloop index="addr" list="#postalAddress#" delimiters="$">


The standard for postal addresses specifies a maximum of 30 characters in six rows.

Other problems to watch out for are timeouts, maximum number of records and access controls lists (ACLs). The default timeout for queries through ColdFusion is 60 seconds. You can specify a longer timeout; however, you may run into the timeout of the server. There's no maximum number of records ColdFusion will ask for. You can specify a MAXROWS amount if you think your query may return an inordinately large result set. Most servers have an internal limit on the maximum number of entries they'll return. You may want to check the server settings.

Access control lists are a way of limiting who can access what information. For instance, the default ACLs in Netscape's Directory Server prevent a user from changing someone else's password and anonymous users from making any changes. You can implement ACLs that prevent certain fields from being returned or return only those fields to specific users. If you know the field exists and the data's there, chances are an ACL is preventing you from seeing it.

ColdFusion queries your LDAP server as an anonymous user. You can, and probably should, set up a user account in the LDAP directory that your CF server can use. You can give that account permission beyond that of an anonymous user but less than the directory administrator. You'll need to include the USERNAME and PASSWORD options in your <CFLDAP> queries.

Going Beyond Simple Queries
Okay. Now that you know how to query an LDAP directory, let's add a record. This is where things start to get really hairy. You have to think carefully about what information you want to store in the directory before you do it. Most LDAP server manuals have detailed guides for implementing a directory structure.

Actually, adding the record is relatively straightforward. You'll need to come up with a distinguished name that matches the one used in your directory server. Next, build the list of required object classes and the attributes list. To actually add the entry, you'll need a username that has sufficient permissions.

In Listing 1, I'm adding Rick Deckard to the Los Angeles Police Department directory. There's no real minimum to the information you must add other than the dn. Your directory server may do syntax checking to make sure you don't add attributes without the appropriate object classes, so it's always a good idea to make sure everything's okay before adding an entry.

In composing the attribute list to add an entry, the object classes come first, followed by a semicolon, then the attributes and their values. Each attribute is separated by a semicolon as well. I build the object class list and the attribute list separately because I sometimes need to add object classes based on the type of user. For instance, if one of my users has an e-mail account, I can easily add the appropriate object classes and attributes.

Modifying Existing Records
Modifying a directory entry is similar to an add. You'll need to construct a list of attributes, all separated by semicolons. If you're adding any object classes, you'll need to construct a new object class list. While it makes sense to us to just pass the additional object classes, most LDAP servers require the entire object class list. The program in Listing 2 will update Deckard's entry in the LAPD directory server.

Rather than trying to figure out what the dn of an entry should be, I do a query for the record I want to modify. I'll use the dn later in the modify query. The additional hit against the directory server doesn't slow down the process significantly.

In the program I use to keep my directory server in sync with our Oracle database, I'll query the Oracle database and do a lookup and modify for each entry. Even with an update of over 6,000 records, my program will usually run in just a few minutes.

Changing the DN
You may find at some time that you need to change the dn for an entry. In setting up my directory server, I initially used a number for the uid portion of the dn. After populating the database, I realized the folly of my ways and wrote a program to change the uid to something more reasonable: the individual's username on our mainframe. Listing 3 changes Deckard's uid from his last name and first initial to his BRU number.

When changing the dn, you can generally change only the leftmost portion. For instance, the dn for me is:

uid=andersdl, ou=people, o=plattsburgh.edu

Using the modifydn query, only the uid=andersdl portion can be changed. It's not possible to move entries around in the tree structure using modifydn. Instead, you'll have to delete the entry and re-create it under the new branch.

Also, you can't use modifydn to change the name of a branch. If you want to change the ou=people branch to ou=employees, you have to remove all the entries under people, then rename it.

Deleting Attributes from an Entry
While you can delete portions of an LDAP entry at the UNIX command line, it's not really possible with ColdFusion. Instead, I do an update and set the values of the fields to null. Listing 4 removes Deckard's manager.

If you've heavily modified an LDAP entry and are concerned that it may contain many unused attributes, simply delete the entire record and re-add it.

Deleting an Entry
If you know the dn, removing an entry requires only one query. To delete the entry, set the query type to "delete" and provide the dn. As with any other query that modifies the directory, you'll need the proper user permissions to delete the entry. Listing 5 deletes Deckard's entry.

The delete operation removes only one entry at a time and will not remove leaf entries. If you need to remove a range of entries, you'll have to loop over the list and do a delete query for each. To delete a branch that has leaf entries, remove all its leaf entries first.

Tying It Together
Your directory server information can be used for the same purposes you'd use an SQL database. Because directory servers aren't SQL servers, there are some caveats.

As I mentioned above, directory queries can be sorted on only one field. If you need to sort on last and first name, you'll need to write some code to postprocess the query.

In some of my applications I use groups on the server to grant access to applications. In certain applications I'll generate a select list from the group. Since group queries come back from the server as comma-delimited lists, they require some conversion before they can be used for further queries. In my application I'll get the list of unique members, then build a filter that'll return the users I want. The code below will take a list of uids and convert it to a filter:

<cfset uidq = "(|">
<cfloop index="value" list="#userlist.uniquemember#" delimiters=",">
<cfif left(trim(value),"3") eq "uid">
<cfset uidq = uidq & "(" & trim(value) & ")">
<cfset uidq = uidq & ")">

One minor frustration is the inability to select attributes using AS, such as you can do in SQL. If you need the equivalent, you can certainly use the query functions (QueryNew, QueryAddRow, QuerySetCell) to reformat the directory. I've found it convenient when working with data from the directory server that's similar to a query from my Oracle server.

Using LDAP for Authentication
For me, the primary purpose of putting up a directory server was authentication. We're trying to reduce the number of passwords our users have to remember. At the same time, we're trying to expand the number of services we offer. Netscape's Directory Server, with its ability to synchronize Windows NT accounts, has proved to be a good fit for us.

I've configured my ColdFusion server to use the directory server for authentication. If you've skimmed the manual, you've probably noticed it can get complicated. Essentially, you can use your directory server as the source for user authentication. I won't go into how to set up security. Ben Forta's book, Advanced ColdFusion Application Development, covers setting up security rather well.

The only difficulty I've run into has been in adding and removing users and groups via the user administration screens in the CF Administrator. This is a known bug in the current version of ColdFusion Server. I have to type in the dn for users and groups that I want added. Unfortunately, removing users means I have to re-create my user lists.

Final Thoughts
Just as with any datasource, it pays to know as much about your directory schema as you can. Knowing what fields are used in your directory and the overall structure of the tree can help immensely in formulating queries. Knowing how LDAP servers work can also be informative. You may want to look at some of the LDAP Web pages listed below.

If you're just starting out with directory servers, try to set up a small test machine. A couple of free LDAP servers run on Linux, so if you have an extra machine, you might want to set it up as your testbed. (By the way, you may have noticed Barbara [Babs] Jansen used in many LDAP examples. If you don't know who she is, search the Internet Movie Database [www.imdb.com] for Martha Smith.)

LDAP Roadmap & FAQ:
www.kingsmountain com ldapRoadmap.shtml
Lightweight Directory Access Protocol:
Netscape Directory Service Docs:
http://home.netscape.com/eng/server/ directory/4.0/

More Stories By David Anderson

David Anderson is a senior programmer/analyst at the University of Buffalo. He specializes in web user experience and technology.

Comments (0)

Share your thoughts on this story.

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

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

IoT & Smart Cities Stories
Moroccanoil®, the global leader in oil-infused beauty, is thrilled to announce the NEW Moroccanoil Color Depositing Masks, a collection of dual-benefit hair masks that deposit pure pigments while providing the treatment benefits of a deep conditioning mask. The collection consists of seven curated shades for commitment-free, beautifully-colored hair that looks and feels healthy.
The textured-hair category is inarguably the hottest in the haircare space today. This has been driven by the proliferation of founder brands started by curly and coily consumers and savvy consumers who increasingly want products specifically for their texture type. This trend is underscored by the latest insights from NaturallyCurly's 2018 TextureTrends report, released today. According to the 2018 TextureTrends Report, more than 80 percent of women with curly and coily hair say they purcha...
The textured-hair category is inarguably the hottest in the haircare space today. This has been driven by the proliferation of founder brands started by curly and coily consumers and savvy consumers who increasingly want products specifically for their texture type. This trend is underscored by the latest insights from NaturallyCurly's 2018 TextureTrends report, released today. According to the 2018 TextureTrends Report, more than 80 percent of women with curly and coily hair say they purcha...
We all love the many benefits of natural plant oils, used as a deap treatment before shampooing, at home or at the beach, but is there an all-in-one solution for everyday intensive nutrition and modern styling?I am passionate about the benefits of natural extracts with tried-and-tested results, which I have used to develop my own brand (lemon for its acid ph, wheat germ for its fortifying action…). I wanted a product which combined caring and styling effects, and which could be used after shampo...
The platform combines the strengths of Singtel's extensive, intelligent network capabilities with Microsoft's cloud expertise to create a unique solution that sets new standards for IoT applications," said Mr Diomedes Kastanis, Head of IoT at Singtel. "Our solution provides speed, transparency and flexibility, paving the way for a more pervasive use of IoT to accelerate enterprises' digitalisation efforts. AI-powered intelligent connectivity over Microsoft Azure will be the fastest connected pat...
There are many examples of disruption in consumer space – Uber disrupting the cab industry, Airbnb disrupting the hospitality industry and so on; but have you wondered who is disrupting support and operations? AISERA helps make businesses and customers successful by offering consumer-like user experience for support and operations. We have built the world’s first AI-driven IT / HR / Cloud / Customer Support and Operations solution.
Codete accelerates their clients growth through technological expertise and experience. Codite team works with organizations to meet the challenges that digitalization presents. Their clients include digital start-ups as well as established enterprises in the IT industry. To stay competitive in a highly innovative IT industry, strong R&D departments and bold spin-off initiatives is a must. Codete Data Science and Software Architects teams help corporate clients to stay up to date with the mod...
At CloudEXPO Silicon Valley, June 24-26, 2019, Digital Transformation (DX) is a major focus with expanded DevOpsSUMMIT and FinTechEXPO programs within the DXWorldEXPO agenda. Successful transformation requires a laser focus on being data-driven and on using all the tools available that enable transformation if they plan to survive over the long term. A total of 88% of Fortune 500 companies from a generation ago are now out of business. Only 12% still survive. Similar percentages are found throug...
Druva is the global leader in Cloud Data Protection and Management, delivering the industry's first data management-as-a-service solution that aggregates data from endpoints, servers and cloud applications and leverages the public cloud to offer a single pane of glass to enable data protection, governance and intelligence-dramatically increasing the availability and visibility of business critical information, while reducing the risk, cost and complexity of managing and protecting it. Druva's...
BMC has unmatched experience in IT management, supporting 92 of the Forbes Global 100, and earning recognition as an ITSM Gartner Magic Quadrant Leader for five years running. Our solutions offer speed, agility, and efficiency to tackle business challenges in the areas of service management, automation, operations, and the mainframe.