Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Ldap Bundle Laravel Package

gepur-it/ldap-bundle

gepur-it/ldap-bundle is a PHP/Symfony bundle that integrates LDAP directory services with your application, offering configuration for connections, user authentication, and directory queries. It helps wire LDAP-backed login and user lookup into Symfony services with minimal setup.

View on GitHub
Deep Wiki
Context7

Getting Started

Before anything else: this is a Symfony bundle, not a Laravel package. The name (ldap-bundle), the DependencyInjection conventions, and the description ("Authorisation bundle fot gepur apps") all point at Symfony's security/DI stack. In a Laravel app you would not install it directly — you'd either port the relevant classes or, more realistically, use ldaprecord-laravel / adldap2 instead. The rest of this assessment assumes you're evaluating it against a Symfony service (or deciding whether to lift logic out of it).

Minimal steps:

composer require gepur-it/ldap-bundle:^5.1

Then register the bundle in config/bundles.php (it was written pre-Flex-autoconfig era, so expect manual registration) and inspect the bundle's DependencyInjection/Configuration.php first — that file is the only reliable documentation. It defines the config tree: connection host/port, base DN, bind DN/password, user search filter, and (for an authorisation bundle) the attribute or group filter used to derive roles.

Look at, in order:

  1. DependencyInjection/Configuration.php — the real API surface (config keys, defaults).
  2. Security/ or Service/ — the user provider / authenticator and the group→role mapping.
  3. Resources/config/services.xml (or .yaml) — service IDs, so you know what to override.

First use case to validate end-to-end: bind to the directory, search for a user by username, authenticate them, then map their LDAP group membership to Symfony roles. Get that working against a throwaway LDAP container before touching your real directory:

docker run -d -p 389:389 -e LDAP_ORGANISATION=Acme \
  -e LDAP_DOMAIN=acme.test -e LDAP_ADMIN_PASSWORD=admin \
  osixia/openldap:1.5.0

If the bundle can't authenticate against a fresh OpenLDAP with a trivially simple config, stop there — the maintenance risk isn't worth it.

Implementation Patterns

Treat LDAP as the credential authority, keep your local user table as the profile store. The pattern that survives contact with real directories is: authenticate against LDAP → look up or create the local User → persist the LDAP-derived roles on that user record → let Symfony's normal session auth take over. This gives you a fallback when the directory is unreachable and lets you attach application data (preferences, audit fields) LDAP knows nothing about.

Map groups, don't hardcode roles. Almost every LDAP authorisation bundle exposes something like a group_filter / role_mapping map. Configure it declaratively rather than in code:

# illustrative — check Configuration.php for the real keys
ldap:
  connection:
    host: '%env(LDAP_HOST)%'
    port: 636
    encryption: ldaps
  base_dn: 'ou=people,dc=acme,dc=test'
  bind_dn: '%env(LDAP_BIND_DN)%'
  bind_password: '%env(LDAP_BIND_PASSWORD)%'
  user_filter: '(uid={username})'
  group_filter: '(member={user_dn})'
  role_map:
    'cn=app-admins,ou=groups,dc=acme,dc=test': ROLE_ADMIN
    'cn=app-users,ou=groups,dc=acme,dc=test': ROLE_USER

Wire credentials through env vars, never the config file. Bind DN passwords in YAML are the classic leak — they end up in a repo, a Docker layer, and a stack trace all at once.

Always keep a break-glass local admin. Configure the bundle to allow a local user provider alongside the LDAP one, or exempt an emergency account. You will need it the first time the directory or VPN goes down and nobody can log in.

Abstract the directory behind an interface. Even if you use the bundle's services directly, wrap them:

interface DirectoryAuthorizerInterface
{
    public function rolesFor(string $username): array;
}

One adapter delegates to the bundle; a second returns hardcoded roles for tests. Directory-dependent tests are slow and flaky, and you'll want to exercise the role-mapping logic without a live LDAP.

Cache group lookups. Role resolution is one or more LDAP searches per login. If the bundle doesn't cache, decorate its service and add a short-TTL cache keyed on the user DN. A 5-minute TTL is enough to make group changes feel immediate without hammering the directory.

Gotchas and Tips

  • Maintenance risk is still the headline, but the picture moved slightly. v5.1.0 landed (after a long dormancy since the 2021 release), so the project isn't strictly abandoned — but the entire changelog for the release is php >=7.4. A single constraint bump is a weak signal: no bugfixes, no security notes, no Symfony 6/7 compatibility work, still one star and zero dependents. Budget for the possibility that you own this code. Pin ^5.1 and vendor-fork it if you adopt it.
  • php >=7.4 is an open-ended constraint, and that cuts both ways. The good news: Composer will no longer block installation on PHP 8.x, so the package is at least installable on a modern runtime. The bad news: >=7.4 has no upper bound, so it will happily install on PHP 8.4 where the removed ldap_control_paged_result*() functions do not exist — you get a runtime Call to undefined function instead of a clean dependency conflict. A declared floor of 7.4 also means the codebase still can't use PHP 8 syntax, so don't read this as "modernised". Run the auth flow on your actual production PHP version before committing.
  • Symfony version compatibility is the unresolved question. The 5.1.0 note says nothing about symfony/framework-bundle or symfony/security-bundle. If the constraints are still ^4.4|^5.x, the security system change in 6.x (authenticators replaced guards, security.yaml provider syntax changed) means you may be looking at a rewrite rather than an install. Check composer.json before you plan anything.
  • LDAP filter injection. user_filter: '(uid={username})' with an unescaped username lets *)(uid=* through. Verify the bundle calls ldap_escape($username, '', LDAP_ESCAPE_FILTER). If it doesn't, wrap it yourself. This is the single most common bug in hand-rolled LDAP integrations, and a release that only touched composer.json is no evidence it was fixed.
  • Distinguish failure modes in your error handling. "Server unreachable", "bind failed", "user not found", and "wrong password" must not all collapse into "Invalid credentials". Log them distinctly — debugging LDAP blind is miserable. ldapsearch -H ldaps://host -D "$BIND_DN" -W -b "$BASE_DN" '(uid=someone)' outside the app is always step one.
  • ldaps/TLS. Certificate validation, CA bundles, and self-signed certs in dev account for a large share of "it works with ldapsearch but not the app" reports. Check whether the bundle sets LDAP_OPT_X_TLS_REQUIRE_CERT and whether it honours your system CA store.
  • Paged results and size limits. Active Directory caps searches at 1000 results by default. If role mapping iterates group membership broadly, you'll silently get truncated results. Look for ldap_control_paged_result usage — the v5.1.0 release did not change the PHP floor beyond 7.4, so the removed-in-8.1 functions may still be in play here.
  • Nested groups. AD nests groups; a naive (member={user_dn}) filter misses inherited memberships. Decide early whether you need LDAP_MATCHING_RULE_IN_CHAIN (1.2.840.113556.1.4.1941) and whether the bundle can express it.
  • Extension points. Services are defined in the bundle's DI config, so a compiler pass or a service definition in your app's services.yaml with the same ID will override them. That, plus a custom user provider implementing UserProviderInterface, is your escape hatch when the bundled behaviour doesn't fit.
  • Debugging aid. Enable Symfony's ldap logging channel if present, and set kernel.debug so failed binds surface the underlying LDAP error code rather than a generic BadCredentialsException.

Bottom line for day-to-day use: v5.1.0 is a compatibility unlock, not a revival — it lets Composer install the bundle on PHP 8 but does nothing about filter escaping, Symfony 6/7 security changes, or the removed paged-result functions. The concepts are standard (bind, search, map groups to roles) and worth borrowing; the code is not something to depend on unexamined. Read the two or three classes that matter, verify filter escaping and runtime behaviour on your actual PHP version, and be prepared to vendor it in. If you're on Laravel, skip it entirely and use a maintained LDAP package — this one will not meet you halfway.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
cgv/localized-resource