LDAP authentication¶
naf/auth-ldap verifies credentials against an LDAP directory through the existing Auth
provider contract. The application maps a verified directory entry to its own local identity.
Use it when an organization manages credentials in a directory but application accounts and
permissions remain local.
Required packages
In an existing NAF application:
composer require naf/auth-ldap
Also installs these transitive dependencies: naf/auth.
How it fits¶
LdapProvider implements Auth's ProviderInterface. The directory verifies credentials;
explicit mapping callbacks associate a stable directory subject with a local account ID.
The local account provider supplies the identity and permissions.
| Callback | Input | Return |
|---|---|---|
accountForSubject |
Directory subject string | Local account ID, or null if unlinked |
subjectForAccount |
Local account ID string | Directory subject, or null if unlinked |
The plugin does not create accounts or link by email. Store links in application-owned persistence and use the immutable directory subject, rather than a changeable username. A missing link prevents authentication.
The directory alone verifies the submitted password. After a successful bind, the local
account provider is called through find() to load the linked identity; its authenticate()
method never receives the directory password. Keep local account loading separate from
directory credential verification when adapting this integration.
Session restoration calls the directory again through find(). A missing or disallowed
subject prevents restoration; directory outages throw instead of falling back to local
credentials. Auth also checks local account activity. With session persistence enabled,
successful login rotates the session ID.
Configuring the connection¶
Install PHP's ext-ldap and provide a readable trusted CA file. NativeDirectory validates
these constructor settings before opening a connection:
- LDAPS, or StartTLS made mandatory, with a CA file that exists.
- Non-anonymous search credentials and a base DN.
- An immutable subject attribute —
entryUUIDby default. - An allowed-account filter, parenthesised.
- A timeout between 1 and 30 seconds.
A URL carrying credentials, a base DN, a query string or a fragment is refused, as is an
attribute name that would break out of an LDAP filter. Values are escaped with
LDAP_ESCAPE_FILTER, referrals are disabled, an ambiguous search is refused rather than
guessed at, and a directory that cannot be reached fails closed instead of falling back to
local credentials.
TLS trust and disabled accounts
PHP/OpenLDAP TLS options are process-global. Use a consistent trust configuration for directories accessed by the same process.
Configure allowedFilter to exclude disabled accounts according to your directory's
schema. The default object-class filter alone does not enforce that rule.
For Active Directory, set the account attribute, the stable subject representation and the
disabled-account filter to match your directory before enabling it. The shipped adapter
targets textual subjects such as OpenLDAP's entryUUID.
Register the provider¶
This reference fragment belongs in root bootstrap.php, before app()->run(). It assumes:
$accountsimplementsProviderInterfacefor existing local accounts.$accountForSubjectand$subjectForAccountare closures implementing the mappings above.ldap:url,ldap:base_dn,ldap:bind_dn,ldap:bind_password,ldap:ca_fileandldap:allowed_filterare application configuration strings.
Keep the service password in a protected environment value. These application configuration keys are read by this fragment; the plugin does not discover or register a provider from them.
use Naf\Auth\Ldap\LdapProvider;
use Naf\Auth\Ldap\NativeDirectory;
use function Naf\config;
use function Naf\Auth\auth;
$directory = new NativeDirectory(
url: config('ldap:url'),
baseDn: config('ldap:base_dn'),
bindDn: config('ldap:bind_dn'),
bindPassword: config('ldap:bind_password'),
caFile: config('ldap:ca_file'),
allowedFilter: config('ldap:allowed_filter'),
);
$provider = new LdapProvider($directory, $accountForSubject, $subjectForAccount, $accounts);
auth()->addProvider('directory', $provider);
Pass 'directory' as the provider name when calling auth()->authenticate() with
PasswordCredentials. See multiple account sources. Optional
NativeDirectory arguments default to usernameAttribute: 'uid',
subjectAttribute: 'entryUUID' and timeout: 5 seconds.
Verify the directory integration¶
Before deployment, test a linked active account, an unlinked account, an incorrect password, a disabled directory subject, a disabled local account and a directory outage against your actual trusted TLS directory. Verify that restoration after disabling a subject fails on the next request. Do not log submitted passwords.
The package's fake-directory tests verify provider contracts and configuration rejection. They do not verify your network, certificate trust, directory schema or account mappings.