symfony/ldap
Symfony LDAP Component: a PHP LDAP client built on top of the PHP ldap extension. Stable since Symfony 3.1 (earlier versions were internal and may break). Includes docs and contribution resources via the main Symfony repository.
Install the Package
composer require symfony/ldap
Ensure the php-ldap extension is enabled in your php.ini or Docker container.
Basic Connection
Create an LDAP client instance in a Laravel service provider (e.g., AppServiceProvider):
use Symfony\Component\Ldap\LdapClient;
public function register()
{
$this->app->singleton(LdapClient::class, function ($app) {
return new LdapClient('ldap://your-ldap-server:389');
});
}
First Use Case: User Authentication Bind a user to verify credentials:
use Symfony\Component\Ldap\Entry;
$ldap = $this->app->make(LdapClient::class);
$userDn = 'uid=john.doe,ou=users,dc=example,dc=com';
$password = 'securePassword123';
try {
$ldap->bind($userDn, $password);
// Authentication successful
} catch (\Symfony\Component\Ldap\Exception\ConnectionException $e) {
// Handle authentication failure
}
Search for Users Query LDAP for user entries:
$query = new \Symfony\Component\Ldap\Query();
$query->where('objectClass')->equals('person');
$query->where('uid')->equals('john.doe');
$results = $ldap->search($query);
$entries = $results->toArray();
$ldap->bind($userDn, $password);
$ldap->bind();
$ldap->bind($userDn, null, ['SASL_MECHANISM' => 'GSSAPI']);
$entry = Entry::fromData(
'uid=john.doe,ou=users,dc=example,dc=com',
[
'cn' => ['John Doe'],
'sn' => ['Doe'],
'mail' => ['john.doe@example.com'],
'objectClass' => ['top', 'person', 'organizationalPerson'],
]
);
$ldap->update($entry);
$groupDn = 'cn=developers,ou=groups,dc=example,dc=com';
$ldap->modify($groupDn, [
'member' => [
'uid=john.doe,ou=users,dc=example,dc=com',
'uid=jane.smith,ou=users,dc=example,dc=com',
],
]);
$query = new Query();
$query->where('memberOf')->equals('cn=admins,ou=groups,dc=example,dc=com');
$query->where('objectClass')->equals('person');
$results = $ldap->search($query);
use Illuminate\Contracts\Auth\Authenticatable;
use Symfony\Component\Ldap\Entry;
class LdapUserProvider implements Authenticatable
{
public function retrieveById($identifier)
{
// Fetch user from LDAP
}
public function retrieveByCredentials(array $credentials)
{
$ldap = app(LdapClient::class);
$userDn = $credentials['username'];
$ldap->bind($userDn, $credentials['password']);
return $this->createModelFromEntry($ldap->search(new Query()->where('dn')->equals($userDn))->first());
}
}
$this->app->bind(LdapClient::class, function ($app) {
$config = config('ldap');
return new LdapClient(
$config['host'],
$config['port'] ?? 389,
[
'options' => [
'protocol_version' => $config['protocol_version'] ?? 3,
'referrals' => $config['follow_referrals'] ?? false,
],
]
);
});
config/ldap.php:
return [
'host' => env('LDAP_HOST', 'ldap.example.com'),
'port' => env('LDAP_PORT', 389),
'base_dn' => env('LDAP_BASE_DN', 'dc=example,dc=com'),
'username' => env('LDAP_BIND_DN', 'cn=admin,dc=example,dc=com'),
'password' => env('LDAP_BIND_PASSWORD', ''),
'protocol_version' => 3,
'follow_referrals' => false,
];
$cacheKey = 'ldap_users_' . md5($query->getQuery());
$results = Cache::remember($cacheKey, now()->addHours(1), function () use ($ldap, $query) {
return $ldap->search($query);
});
try {
$ldap->search($query);
} catch (\Symfony\Component\Ldap\Exception\ConnectionException $e) {
Log::error('LDAP connection failed: ' . $e->getMessage());
throw new \RuntimeException('LDAP service unavailable');
}
Connection Timeouts
$ldap = new LdapClient('ldap://example.com', [
'options' => [
'default_socket_timeout' => 5, // 5 seconds
],
]);
Referrals
$ldap = new LdapClient('ldap://example.com', [
'options' => [
'referrals' => false,
],
]);
Schema Mismatches
Entry::getAttribute() with a fallback:
$email = $entry->getAttribute('mail')[0] ?? null;
Case Sensitivity in DN
$normalizedDn = strtolower($userDn);
Memory Leaks with Large Results
Ldap\Result::toIterator() to stream results:
foreach ($results->toIterator() as $entry) {
// Process entry
}
Enable LDAP Debugging
LDAP_DEBUG environment variable:
export LDAP_DEBUG=1
ldap_set_option(null, LDAP_OPT_DEBUG_LEVEL, 7);
Log Raw LDAP Responses
$adapter = new \Symfony\Component\Ldap\Adapter\ExtLdapAdapter();
$adapter->setLogger(new \Monolog\Logger('ldap'));
$ldap = new LdapClient('ldap://example.com', ['adapter' => $adapter]);
Validate LDAP Filters
ldap_escape function to sanitize inputs:
$safeUsername = ldap_escape($username, null, LDAP_ESCAPE_FILTER);
$query->where('uid')->equals($safeUsername);
class LdapUserMapper
{
public function mapToModel(Entry $
How can I help you explore Laravel packages today?