This guide is written by the team that builds Casdoor and describes the standards as published (listed under Sources), with notes on how Casdoor implements them as of November 7, 2026. Spotted a mistake? Tell us.
LDAP authentication is a bind: a client sends a distinguished name (DN) and a password to a directory server, and the server answers yes or no. There is no token, no assertion and no session that other applications share. The application asks the directory every time it needs to check a password.
That is both the strength and the limit of LDAP. It is simple, universal and still the backbone of enterprise directories, including Active Directory. It is also not single sign-on.
The pieces that matter
| Term | Meaning |
|---|---|
| Entry | One object in the directory: a user, a group, a computer |
| DN | The full path of an entry, for example uid=alice,ou=people,dc=example,dc=com |
| Base DN | Where searches start, for example dc=example,dc=com |
| Attribute | A field on an entry: uid, mail, cn, memberOf |
| Filter | A search expression, for example (uid=alice) |
| Bind | The authentication operation: DN plus password |
How a bind works
The common pattern has two steps:
- The application connects to the directory (usually port 389, or 636 for LDAPS).
- It sends a simple bind with the user's DN and password.
- The server checks the password against the stored hash and returns a result: success, invalid credentials, or an error.
Many applications cannot build the user's DN from what the user typed, because people sign in with an email address or a short username. Those applications use a service account:
- Bind as the service account (a read-only directory user).
- Search under the base DN for the user, for example (mail=alice@example.com).
- Read the user's DN from the result.
- Bind again as that DN with the password the user typed.
This search-then-bind pattern is the one most web applications implement. It needs a service account with search rights, and the search filter must be exact: a filter that matches the wrong entry, or more than one entry, is a security bug.
Simple bind vs SASL
- Simple bind sends the DN and password. It must run over TLS, or the password crosses the network in the clear.
- SASL covers other mechanisms, including Kerberos (GSSAPI) and DIGEST-MD5. Active Directory environments often use GSSAPI for integrated Windows authentication.
For a web application, simple bind over LDAPS or StartTLS is the normal choice.
TLS is not optional
Two ways to encrypt:
- LDAPS: TLS from the first byte, usually port 636.
- StartTLS: connect on 389, then upgrade the connection before sending the bind.
Without TLS, anyone on the network path can read the bind and replay it. Also check the server certificate: a self-signed certificate with verification disabled is a common shortcut that quietly removes the protection.
Active Directory specifics
AD speaks LDAP, but with its own conventions:
- Users can sign in with userPrincipalName (alice@example.com) or sAMAccountName (alice), not necessarily the DN.
- Group membership is exposed through memberOf, but large groups and nested groups need the matching rule LDAP_MATCHING_RULE_IN_CHAIN (1.2.840.113556.1.4.1941).
- AD also uses Kerberos; LDAP is the directory access protocol, Kerberos is the domain authentication protocol.
- Some attributes are constructed and cannot be filtered like ordinary attributes.
OpenLDAP and other directories follow the schemas you load. Do not assume AD's attribute names exist everywhere.
The result codes you will see
| Code | Name | What it usually means |
|---|---|---|
| 0 | success | Bind accepted |
| 32 | noSuchObject | Base DN or user DN does not exist |
| 34 | invalidDNSyntax | The DN is malformed, often an unescaped comma or backslash |
| 49 | invalidCredentials | Wrong password, wrong DN, expired account or locked account |
| 50 | insufficientAccessRights | The service account cannot read the entry or attribute |
| 51 | busy | Server overloaded or connection pool exhausted |
| 52 | unavailable | Server down, wrong port, or TLS handshake failed |
Code 49 is deliberately vague. The directory will not tell an attacker whether the account exists, so your application cannot either. Log the DN you tried and the server's diagnostic message, not just "login failed".
LDAP vs SSO
LDAP authenticates an application against a directory. The application still shows a login form, the user still types a password for that application, and every application keeps its own session. It gives you one set of credentials, not one login.
SSO goes further: the user signs in once at an identity provider, and applications accept a SAML assertion or OIDC token instead of a password. If your goal is "employees sign in once to every app", LDAP alone does not get you there. The usual architecture keeps the directory for legacy systems and puts an identity provider in front of the modern apps.
Where Casdoor fits
Casdoor can act as an LDAP server for applications that only speak LDAP, so those apps can authenticate against Casdoor's user directory without their own account store. It also serves OIDC, SAML and CAS for applications that support federation, and it can broker to upstream providers. That lets one directory cover old and new applications. See the LDAP server documentation.
Checklist for a working LDAP integration
- Use LDAPS or StartTLS; verify the server certificate.
- Use a dedicated service account with read-only search rights, not an admin account.
- Set an explicit base DN and a filter that can match only one user.
- Escape user input in filters, or a crafted username can change the search.
- Set connect and read timeouts; a directory outage should fail closed, not hang the login page.
- Rate-limit failed binds, and lock or alert on repeated failures.
- Log the result code and the diagnostic message, not the password.
- Test with a locked account, an expired password, a user outside the base DN and a server certificate rotation.
FAQ
Is LDAP authentication secure? It can be, if every bind runs over TLS, the service account is read-only, filter input is escaped and failed attempts are rate-limited. Plain LDAP on port 389 without TLS sends passwords in the clear.
What is the difference between LDAP bind and LDAP search? A bind proves an identity and a password. A search finds entries and attributes. Most login flows use a service account to search, then a bind as the user to verify the password.
Does LDAP support single sign-on? Not by itself. LDAP gives applications one credential store, but each application authenticates separately. True SSO needs SAML, OIDC or a similar federation protocol.
Why does LDAP authentication fail with code 49? The server rejects the credentials without saying why: wrong password, wrong DN, expired password, disabled or locked account, or a bind over an unencrypted connection that the server refuses. Check the diagnostic message and test the same DN with a known-good password.
Can Active Directory use LDAP? Yes. Active Directory Domain Services exposes LDAP on port 389 and LDAPS on 636. AD adds Kerberos, its own schema and its own attribute conventions on top.
Related reading: LDAP vs Active Directory, Kerberos vs LDAP, LDAP vs RADIUS and what is single sign-on.
Casdoor is open source and self-hostable, with an LDAP server and OIDC, SAML and CAS support in one identity provider. The hosted option starts at $9 per month with no per-user fees.
Sources
- RFC 4511: Lightweight Directory Access Protocol (LDAP)
- RFC 4513: LDAP Authentication Methods
- OpenLDAP 2.6 administrator guide
- Casdoor docs: LDAP server
Product names are trademarks of their respective owners.