The following sections present advanced topics that enable you to use LDAP directories more effectively.
LDAP attribute values can contain commas. The cfldap
tag normally uses commas to separate attribute values in a value list. Similarly, an attribute can contain a semicolon, which cfldap
normally uses to delimit (separate) attributes in an attribute list. To override the default separator and delimiter characters, you use the cfldap
tag separator
and delimiter
attributes.
For example, assume you want to add the following attributes to an LDAP entry:
cn=Proctor, Goodman, and Jones
description=Friends of the company; Rationalists
Use the cfldap
tag in the following way:
<cfldap action="modify"
modifyType="add" attributes="cn=Proctor, Goodman, and Jones: description=Friends of the company; Rationalists" dn="uid=goodco, ou=People, o=Airius.com" separator="&" delimiter=":" server=#myServer# username=#myUserName# password=#myPassword#>
You can create a searchable Verity collection from LDAP data. building a Verity collection using an LDAP directory, see "Indexing cfldap query results," in Chapter 24.
The ability to generate queries from other queries is very useful when cfldap
queries return complex data. For more information on querying queries, see Chapter 22, "Using Query of Queries"
LDAP v3 exposes a directory's schema information in a special entry in the root DN. You use the directory root subschemaSubentry attribute to access this information.
The following ColdFusion query shows how to get and display the directory schema. It displays information from the schema's object class and attribute type definitions. For object classes, it displays the class name, superior class, required attribute types, and optional attribute types. For attribute types, it displays the type name, type description, and whether the type is single- or multivalued.
The example does not display all the information in the schema. For example, it does not display the matching rules. It also does not display the object class IDs, attribute type IDs, attribute type syntax IDs, or the object class descriptions. (The object class description values are all "Standard Object Class.")
Note: To be able to view the schema for an LDAP server, the server must support LDAP v3.
This example does not work on iPlanet Directory Server 5.0. It does work on a 4.x server.
<html> <head> <title>LDAP Schema</title> </head> <body> <!--- Start at Root DSE to get the subschemaSubentry attribute ---> <cfldap name="EntryList" server="ldap.mycorp.com" action="query" attributes="subschemaSubentry" scope="base" start=""> <!--- Use the DN from the subschemaSubEntry attribute to get the schema ---> <cfldap name="EntryList2" server="ldap.mycorp.com" action="query" attributes="objectclasses, attributetypes" scope="base" filter="objectclass=*" start=#entryList.subschemaSubentry#> <!--- Only one record is returned, so query loop is not required ---> <h2>Object Classes</h2> <table border="1"> <tr> <th>Name</th> <th>Superior class</th> <th>Must have</th> <th>May have</th> </tr> <cfloop index = "thisElement" list = #Entrylist2.objectclasses#> <cfscript> thiselement = Trim(thisElement); nameloc = Find("NAME", thisElement); descloc = Find("DESC", thisElement); suploc = Find("SUP", thisElement); mustloc = Find("MUST", thisElement); mayloc = Find("MAY", thisElement); endloc = Len(thisElement); </cfscript> <tr> <td><cfoutput>#Mid(thisElement, nameloc+6, descloc-nameloc-8)# </cfoutput></td> <cfif #suploc# NEQ 0> <td><cfoutput>#Mid(thisElement, suploc+5, mustloc-suploc-7)# </cfoutput></td> <cfelse> <td>NONE</td> </cfif> <cfif #mayloc# NEQ 0> <td><cfoutput>#Replace(Mid(thisElement, mustloc+6, mayloc-mustloc-9), " $ ", ", ", "all")#</cfoutput></td> <td><cfoutput>#Replace(Mid(thisElement, mayloc+5, endloc-mayloc-8), " $ ", ", ", "all")#</cfoutput></td> <cfelse> <td><cfoutput>#Replace(Mid(thisElement, mustloc+6, endloc-mustloc-9), " $ ", ", ", "all")#</cfoutput></td> <td>NONE</td> </cfif> </tr> </cfloop> </table> <br><br> <h2>Attribute Types</h2> <table border="1" > <tr> <th>Name</th> <th>Description</th> <th>multivalued?</th> </tr> <cfloop index = "thisElement" list = #ReplaceNoCase(EntryList2.attributeTypes, ", alias", "<br> Alias", "all")# delimiters = ","> <cfscript> thiselement = Trim(thisElement); nameloc = Find("NAME", thisElement); descloc = Find("DESC", thisElement); syntaxloc = Find("SYNTAX", thisElement); singleloc = Find("SINGLE", thisElement); endloc = Len(thisElement); </cfscript> <tr> <td><cfoutput>#Mid(thisElement, nameloc+6, descloc-nameloc-8)# </cfoutput></td> <td><cfoutput>#Mid(thisElement, descloc+6, syntaxloc-descloc-8)# </cfoutput></td> <cfif #singleloc# EQ 0> <td><cfoutput>Yes</cfoutput></td> <cfelse> <td><cfoutput>No</cfoutput></td> </cfif> </tr> </cfloop> </table> </body> </html>
cfldap
tag.
ldapschema.cfm
in myapps
under your web root directory and view it in your browser.The following table describes the code and its function:
An LDAP database can be distributed over multiple servers. If the requested information is not on the current server, the LDAP v3 standard provides a mechanism for the server to return a referral to the client that informs the client of an alternate server. (This feature is also included in some LDAP v2-compliant servers.)
ColdFusion can handle referrals automatically. If you specify a nonzero referral
attribute in the cfldap
tag, ColdFusion sends the request to the server specified in the referral.
The referral
attribute value specifies the number of referrals allowed for the request. For example, if the referral
attribute is 1, and server A sends a referral to server B, which then sends a referral to server C, ColdFusion returns an error. If the referral
attribute is 2, and server C has the information, the LDAP request succeeds. The value to use depends on the topology of the distributed LDAP directory, the importance of response speed, and the value of response completeness.
When ColdFusion follows a referral, the rebind
attribute specifies whether ColdFusion uses the cfldap
tag login information in the request to the new server. The default, No, sends an anonymous login to the server.
When you consider how to implement LDAP security, you must consider server security and application security.
The cfldap
tag supports secure socket layer (SSL) v2, security. This security provides certificate-based validation of the LDAP server. It also encrypts data transferred between the ColdFusion Server and the LDAP server, including the user password, and ensures the integrity of data passed between the servers.
The LDAP server sends a certificate that is securely "signed" by a trusted authority and identifies (authenticates) the sender. The ColdFusion server uses the certificate to ensure that the server is valid. The ColdFusion server does not send the LDAP server a certificate, and you must use the cfldap
tag username
and password
attributes to authenticate yourself to the LDAP server.
To use security, first ensure that the LDAP server supports SSL v3 security.
Specify the cfldap
tag secure
attribute as follows:
secure = "cfssl_basic"
<cfldap action="modify"
modifyType="add" atributes="cn=Lizzie" dn="uid=lborden, ou=People, o=Airius.com" server=#myServer# username=#myUserName# password=#myPassword# secure="cfssl_basic" port=636>
The port
attribute specifies the server port used for secure LDAP communications, which is 636 by default. If you do not specify a port, ColdFusion attempts to connect to the default, nonsecure, LDAP port 389.
To ensure application security, you must prevent outsiders from gaining access to the passwords that you use in cfldap
tags. The best way to do this is to use variables for your username
and password
attributes. You can set these variables on one encrypted application page. For more information on securing applications, see Chapter 16, "Securing Applications".