Definition
Yes. ColdFusion can connect to LDAP directories, including Microsoft Active Directory (AD). It does this primarily through the built-in cfldap tag and the underlying Java (JNDI) libraries. With these tools, a ColdFusion application can authenticate users, query directory information (like emails, groups, and DNs), and, with proper permissions, create or modify directory entries.
How It Works
ColdFusion talks to LDAP or Active Directory over the LDAP protocol, using either plain LDAP (port 389 with StartTLS) or LDAPS (LDAP over SSL/TLS on port 636). Internally, the cfldap tag performs a bind (login to LDAP), runs the requested operation, and returns data to your CFML code.
-
Common operations supported by cfldap:
- Query (search for entries)
- Add (create entries)
- Modify (change attributes)
- Delete (remove entries)
- Compare (check if an attribute has a given value)
- Rename (modrdn)
-
Typical attributes you’ll use with AD:
- sAMAccountName, userPrincipalName, cn, mail, memberOf, distinguishedName (DN), objectGUID
- OU, CN, DC components in DNs and search bases
-
- Use LDAPS (ldaps://) or StartTLS to encrypt credentials and data.
- Import the domain controller’s certificate into ColdFusion’s JVM truststore so SSL/TLS handshakes succeed.
Typical Authentication Flow (Active Directory)
A robust pattern for validating a username and password in AD includes two steps:
- Service account lookup
- Bind with a minimally privileged “service account.”
- Search for the user by sAMAccountName or userPrincipalName within a known base DN.
- Retrieve the user’s distinguishedName (DN).
- Credential verification
- Perform a second operation binding as the found user (DN or UPN) with the password the person entered.
- If the bind or a simple base-scope query succeeds, the password is correct. If it fails with an invalid-credential error, the login is rejected.
Why two steps? AD often requires you to know the DN before you can bind as the user. The service account ensures consistent lookups without granting broad privileges.
Syntax Examples (cfldap)
Below are concise patterns you can adapt. These examples assume LDAPS, a dedicated service account, and secure credential storage.
Find the user by UPN (e.g., jdoe@corp.example.com):
<cfldap
action=”query”
name=”qUser”
server=”ad1.corp.example.com”
port=”636″
secure=”yes”
username=”CN=CF Service,OU=Service Accounts,DC=corp,DC=example,DC=com”
password=”#application.secrets.adPassword#”
start=”DC=corp,DC=example,DC=com”
scope=”subtree”
filter=”(userPrincipalName=#lcase(trim(form.username))#)”
attributes=”distinguishedName,cn,mail,memberOf,userPrincipalName”
timeout=”15″>
Verify the user’s password (bind as user’s DN and run a base query):
<cfif qUser.recordCount EQ 1>
Query group memberships (direct memberships):
- From qUser.memberOf you can read group DNs.
- Note: AD nests groups; direct memberOf may not show inherited memberships. Consider recursive checks or application-level traversal if you need nested memberships.
Add or modify entries:
- Use cfldap action=”add” or action=”modify” with the appropriate attribute list, but only with accounts that have write permissions.
Real-World Use Case
Scenario: A corporate intranet written in ColdFusion wants to use the company’s AD for login and role assignment.
- Login form posts username (UPN or sAMAccountName) and password.
- ColdFusion uses a service account to find the user’s DN and profile (mail, display name).
- ColdFusion re-binds as the user to validate the password.
- The application reads memberOf to map AD groups (e.g., “Intranet-Editors” or “Payroll-Viewers”) to application roles.
- On success, ColdFusion stores a session token with user identity, roles, and expiration, and redirects to protected pages.
- On failure, it shows a friendly error and logs error details for admins (without exposing sensitive info).
Benefits:
- Centralized identity, no duplicate passwords in the app.
- Automatic deprovisioning when HR disables a user in AD.
- Easy group-driven authorization.
When to Use Global Catalog vs. Domain Controller
- Global Catalog (GC): Ports 3268 (LDAP) or 3269 (LDAPS)
- Best for forest-wide searches across multiple domains.
- Returns a subset of attributes (Partial Attribute Set). If you need attributes not in the GC, query the domain controller directly.
- Domain Controller (DC): Ports 389 (LDAP) or 636 (LDAPS)
- Best for authoritative, full-attribute queries and updates in a specific domain.
If you get referrals or multi-domain complexity, you can:
- Query the GC first to find the user location.
- Then query the user’s domain controller for full attributes or updates.
- Optionally configure referral chasing (cfldap includes a referral attribute in recent versions; verify your ColdFusion version).
Best practices and Security
- Always use encryption
- Prefer LDAPS (port 636) or StartTLS on 389.
- Import the DC or CA certificate into the ColdFusion JVM truststore (cacerts) so the handshake succeeds.
- Use least privilege
- Service accounts should be read-only unless you must write to AD.
- Don’t store service account passwords in code; use environment secrets or encrypted storage.
- Sanitize and escape filters
- Escape special characters in LDAP filters (e.g., backslash, parentheses, asterisks) to prevent malformed queries and LDAP injection.
- Timeouts and retries
- Set timeout to avoid hanging threads.
- Deal gracefully with transient network errors.
- Plan for paging and size limits
- AD limits search results (commonly 1000 entries). Limit searches with filters, organizational units (OUs), and maxrows. If you need many entries, implement paged searches (via JNDI) or careful batching.
- Handle nested groups
- memberOf shows direct memberships. If your authorization relies on nested groups, implement recursion or queries that resolve group hierarchies.
- Consider the GC for discovery
- Use the Global Catalog to find the user across the forest, then query the domain controller for final details.
- Log carefully
- Log error codes and context (e.g., LDAP error 49 for invalid credentials) but never log passwords.
Troubleshooting and Tips
- Invalid credentials (LDAP error 49)
- User’s password is wrong, account is locked, expired, or requires reset. Log the condition but keep messages to users generic.
- SSL/TLS handshake failures
- Usually certificate trust issues. Import the domain controller’s certificate chain into ColdFusion’s JVM truststore and restart CF.
- Size limit exceeded
- Narrow the search filter, search specific OUs, or implement paging with Java/JNDI if needed.
- Referral or multi-domain issues
- Use the Global Catalog or enable referral chasing. Confirm your cfldap supports the referral attribute or use Java for advanced control.
- Escaping LDAP filters
- Replace special characters. Example:
- Left parenthesis: (
- Right parenthesis: )
- Asterisk: *
- Backslash: \
- Null byte: 00
- Use a helper function to sanitize user input before building filters.
- Replace special characters. Example:
Key Points
- ColdFusion can directly integrate with LDAP/Active Directory via cfldap and Java/JNDI.
- Use a two-step process: look up user DN with a service account, then bind as the user to verify the password.
- Prefer LDAPS or StartTLS; import certificates into the CF JVM truststore.
- Map AD groups to application roles for flexible authorization.
- Be mindful of AD limits (1000 entries), nested groups, and multi-domain searches.
Summary Points (Key Takeaways)
- Yes, ColdFusion connects to LDAP/AD using the cfldap tag and Java JNDI.
- Use secure connections (LDAPS/StartTLS) and a least-privilege service account.
- Authenticate by searching for the user DN, then binding as the user.
- Handle group membership, nested groups, and directory limits thoughtfully.
- For cross-domain searches, leverage the Global Catalog and consider referral settings.
FAQ
Does ColdFusion support LDAPS and StartTLS?
Yes. You can use cfldap with secure=”yes” for LDAPS on port 636. StartTLS on port 389 is also supported by the underlying Java LDAP provider. Ensure the ColdFusion JVM trusts the LDAP server certificate by importing it into the cacerts truststore, then restart ColdFusion.
How do I validate a user’s password in Active Directory from ColdFusion?
Search for the user with a service account to get their DN, then attempt a base-scope query while binding as that DN with the provided password. If the bind/query succeeds, the credentials are valid; if it throws an invalid-credential error, reject the login.
Can I modify users or reset passwords in AD using ColdFusion?
Yes, if your service account has the necessary permissions and you use cfldap action=”modify” or action=”add”. For password resets and sensitive operations, AD often requires SSL/TLS and specific control flags. Test in a staging environment and coordinate with your AD administrators.
How do I search across multiple domains in a forest?
Use the Global Catalog (ports 3268/3269) to find the user regardless of domain, then query the user’s domain controller for full attributes or updates. You can also enable referral chasing if your cfldap version supports it, or fall back to Java/JNDI for advanced control.
What’s the recommended way to identify users—sAMAccountName or userPrincipalName?
userPrincipalName (UPN, like user@domain.com) is unambiguous across domains and often works well for login forms. sAMAccountName can be ambiguous in multi-domain forests; if you use it, include the domain (DOMAIN\user) or constrain searches to the correct domain/OU.
