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

Simple Ldap Bundle Laravel Package

yunai39/simple-ldap-bundle

A lightweight LDAP bundle for PHP applications that simplifies connecting to directory servers, authenticating users, and running common LDAP queries. It wraps PHP's LDAP extension with straightforward configuration for quick integration.

View on GitHub
Deep Wiki
Context7

Getting Started

First, the mismatch: yunai39/simple-ldap-bundle is a Symfony bundle, not a Laravel package. It ships no service provider, no facade, no config/ publish tag, and no Laravel-compatible discovery. If you are building a Laravel app, you cannot composer require this and call it — you would be fighting Symfony's Kernel, bundles.php, firewall system, and event dispatcher. Treat it as reference material for LDAP auth logic, not a dependency.

If you're on a Symfony 2.x/3.x project that already uses it:

  1. composer require yunai39/simple-ldap-bundle (pin the tag — see Gotchas).
  2. Register in app/AppKernel.php: new Yunai39\Bundle\SimpleLdapBundle\SimpleLdapBundle().
  3. Read DependencyInjection/Configuration.php first — that file is the real documentation, since the README is minimal. It tells you the exact config tree (host, port, base DN, bind DN/password, user filter, attribute mapping).
  4. Configure in config.yml under simple_ldap: and wire it into a security.firewalls entry.
  5. First realistic use case: form login against an LDAP directory, where the bundle providers the user provider and auth listener.

If you're on Laravel: skip this. Use directorytree/ldaprecord-laravel or adldap2/adldap2-laravel. If you must borrow, read the bundle's user provider class and reimplement as a custom Illuminate\Contracts\Auth\UserProvider.

Where to look first in the repo: DependencyInjection/, Security/ (listener + user provider), and Resources/config/. Those three directories contain 90% of the behavior.

Implementation Patterns

Bind-then-search (the standard pattern this bundle encodes):

  1. Open an anonymous or service-account bind to the directory.
  2. Search the base DN for the user with a filter like (uid=%s) or (sAMAccountName=%s).
  3. Retrieve the user's DN.
  4. Re-bind as that DN using the submitted password to validate credentials.
  5. Load or hydrate a local User object keyed by the LDAP attribute you mapped (email, username, DN).

Do not skip step 4 and just compare passwords against a search result — you must bind to actually authenticate.

Firewall wiring (Symfony):

security:
  providers:
    ldap:
      simple_ldap: ~
  firewalls:
    main:
      simple_ldap: ~          # the listener
      form_login:
        provider: ldap

Laravel translation of the pattern — implement Illuminate\Contracts\Auth\UserProvider:

  • retrieveById → search directory by DN or mapped ID.
  • retrieveByCredentials → run the LDAP search filter, return a GenericUser or EloquentUser.
  • validateCredentials → perform the rebind with the submitted password.
  • Cache the directory connection (singleton) to avoid a bind per request; LDAP handshakes are slow.

Sync/local-hybrid pattern: LDAP for authentication, local DB for authorization. On first successful login, firstOrCreate the user locally, hash nothing (LDAP owns the password), and store the DN + mapped attributes. This avoids querying LDAP on every page load and decouples roles/permissions from directory schema.

Group/role mapping: Extend the user provider to also read memberOf (AD) or groupMembership (OpenLDAP) during the search, flatten to role names, and map to your app's roles. Do this in a decorator around the provider, not by editing the bundle — the bundle won't be maintained.

Gotchas and Tips

  • Abandoned. 1 star, 0 dependents, last release 2017-02-08. That predates Symfony 4, Flex, PHP 7.2, and every modern PHP security baseline. LDAP auth is a security boundary — do not deploy this unpatched into a live auth flow. Vendor-fork it and review the bind/listener code yourself.
  • Version pinning is mandatory: composer require yunai39/simple-ldap-bundle:1.0.* (or whatever the exact tag is). Without a pin, Composer may resolve to a dev-master that was never tagged.
  • PHP compatibility: the 2017 vintage likely uses each(), create_function-era idioms, or non-return-typed signatures. Expect PHP 8 deprecations and possible fatals. Run composer why-not php 8.2 before committing.
  • Laravel developers specifically: there is no path to dropping this into Laravel. Bundle registration, the SimpleLdapBundle::boot() lifecycle, and security.yaml all assume Symfony. The realistic move is to read the ~3 relevant classes and port them, or use LdapRecord.
  • LDAP injection: user-supplied search filters must be escaped per RFC 4515 (\2a, \28, \29, \5c, \00). Verify the bundle escapes; older code often concatenates uid= values directly.
  • DN escaping in binds: commas in CNs (CN=Smith, John,OU=...) must be escaped as \, when constructing the bind DN from a stored value. Test with names containing commas and +.
  • ldap vs ldaps / StartTLS: plain ldap/389 sends the password in cleartext. Use ldaps/636 with a valid CA, or StartTLS with LDAP_OPT_X_TLS_REQUIRE_CERT. The bundle's config may not expose a StartTLS toggle — that's a common reason to fork.
  • AD vs OpenLDAP differences: AD requires sAMAccountName (not uid), may need DOMAIN\user form on bind, and returns memberOf; OpenLDAP uses uid and needs groupMembership. The filter and base DN must be tuned per directory.
  • Empty-password anonymous bind: many LDAP servers accept a bind with an empty password as an anonymous bind and return success. Explicitly reject empty passwords before calling bind, or you reintroduce the classic LDAP auth bypass.
  • Debugging: ldap_set_option(NULL, LDAP_OPT_DEBUG_LEVEL, 7) gives verbose stderr traces; ldap_error($conn) after every call tells you whether you're getting Invalid credentials (49) (bad password), No such object (32) (bad base DN), or a TLS failure.
  • Extension point: the clean hook is Symfony's security.authentication.provider / custom UserProviderInterface — wrap or replace the bundle's provider, keep the bundle for its connection glue, and don't touch vendor/ so updates (however rare) don't clobber your code.
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.
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib