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

Ldaprecord Bundle Laravel Package

iter8/ldaprecord-bundle

A Symfony bundle that integrates LdapRecord for easy LDAP authentication and directory queries, with ActiveRecord-style models, fluent querying, and simple configuration for connecting to LDAP servers.

View on GitHub
Deep Wiki
Context7

Getting Started

  1. Check your platform: v4.0 requires PHP 8.1+ and Symfony 6.1+. Install:

    composer require iter8/ldaprecord-bundle:^4.0
    

    If you register manually, note the bundle class namespace changed in v4:

    // config/bundles.php
    // Old (v3.x):  Iter8\Bundle\LdapRecordBundle\Iter8LdapRecordBundle::class => ['all' => true],
    // New (v4.x):
    Iter8\LdapRecordBundle\Iter8LdapRecordBundle::class => ['all' => true],
    

    Flex should handle this for new installs; existing projects upgrading from v3 must update the entry.

  2. Open the bundle’s DependencyInjection/Configuration.php and README.md first. It is still a thin Symfony wrapper around LdapRecord, so the important details are the config root key, supported connection options, and whether LdapRecord\Container is registered as a service. v4 ships against LdapRecord v3 — skim LdapRecord’s upgrade guide if you are porting code from v2.

  3. Configure at least one connection. The config tree generally mirrors LdapRecord’s native connection array:

    # config/packages/ldaprecord.yaml
    ldaprecord:
        connections:
            default:
                hosts: ['%env(LDAP_HOST)%']
                base_dn: '%env(LDAP_BASE_DN)%'
                username: '%env(LDAP_BIND_DN)%'
                password: '%env(LDAP_BIND_PASSWORD)%'
                port: 389
                use_tls: true
    

    Confirm the real root key with:

    bin/console config:dump-reference ldaprecord
    bin/console debug:config ldaprecord
    
  4. First use case: define a model and query the directory. The bundle’s main value is that it bootstraps LdapRecord’s container/connections from Symfony config, so model queries work without manual connection setup:

    namespace App\Ldap;
    
    use LdapRecord\Models\Model;
    
    class User extends Model
    {
        protected $connection = 'default';
    
        protected $objectClasses = [
            'top',
            'person',
            'organizationalPerson',
            'inetOrgPerson',
        ];
    }
    
    $user = \App\Ldap\User::where('mail', '=', $email)->first();
    
    if ($user) {
        $displayName = $user->getFirstAttribute('displayName');
    }
    

Implementation Patterns

Bind models to explicit connections. If you have more than one directory, name connections clearly (default, ad, openldap) and set $connection on each model. Do not rely on implicit ordering or assume the bundle’s “default” matches your naming.

class AdUser extends Model
{
    protected $connection = 'ad';
    protected $objectClasses = ['top', 'person', 'organizationalPerson', 'user'];
}

Use an authenticator/service layer rather than putting LDAP calls in controllers. A Symfony authenticator can validate credentials against LdapRecord and then load or provision a local user:

use LdapRecord\Container;

$connection = Container::getConnection('default');

if (!$connection->auth()->attempt($username, $password)) {
    throw new BadCredentialsException('Invalid LDAP credentials.');
}

$entry = \App\Ldap\User::where('uid', '=', $username)->firstOrFail();

Sync directory attributes into local entities on login or via a command. LDAP is usually the identity source, not the application database. Map a small, explicit set of attributes (mail, displayName, uid, memberOf) and keep the mapping in one service.

Use LdapRecord’s query builder instead of raw filters. Prefer where(), first(), get(), and model methods. If you must build raw filters, escape user input carefully to avoid LDAP filter injection. The query-builder surface is stable between LdapRecord v2 and v3, so most common patterns port cleanly.

Handle large directories with pagination/chunking. LDAP servers often cap results (commonly 1000 entries). For imports, iterate in pages or chunks rather than get() on a broad search.

Keep directory-specific behavior in subclasses. Active Directory and OpenLDAP differ in attributes, object classes, and authentication semantics. Use separate models or a shared base model plus directory-specific subclasses.

Test with a fake connection or thin adapter. Isolate LDAP behind your own service interface, or swap in LdapRecord’s testing/fake connection where available. This keeps unit tests fast and avoids requiring a live directory in CI.

Use console commands for synchronization. Long-running imports belong in Symfony commands, with progress output, batching, and idempotent upserts.

Gotchas and Tips

  • v4 breaking changes: The bundle class namespace moved to Iter8\LdapRecordBundle\Iter8LdapRecordBundle (previously Iter8\Bundle\LdapRecordBundle\Iter8LdapRecordBundle). Any code, imports, or config/bundles.php entries referencing the old FQCN will break at container build. Grep for Iter8\\Bundle\\LdapRecordBundle when upgrading.
  • Minimum versions bumped to PHP 8.1 / Symfony 6.1. Projects on PHP 8.0 or Symfony 5.4/6.0 must either upgrade the platform or stay pinned to v3.
  • LdapRecord v2 → v3 upgrade. The bundle now requires LdapRecord v3. Read LdapRecord’s own upgrade notes before bumping; model/connection/query APIs are mostly stable but review auth, pagination, and testing helpers that your code relies on.
  • Config key uncertainty: Confirm the root key and option names from Configuration.php rather than copying examples from Laravel. Use config:dump-reference and debug:config.
  • Default connection naming: LdapRecord commonly expects a connection named default. If your bundle config names it something else, set the model’s $connection explicitly or configure the default alias.
  • Credentials and env vars: Use %env()% for bind DN/password. Watch quoting and special characters in passwords; test with a real ldapsearch/ldaps connection first.
  • TLS/SSL: use_tls and use_ssl are not interchangeable. Verify port, certificate trust, and whether your server requires StartTLS. Test outside Symfony before debugging bundle wiring.
  • Pagination limits: Do not assume a search returns every entry. Use pagination/chunking for imports and admin screens.
  • Attribute values are often arrays: Use getFirstAttribute() when you expect a scalar, and handle missing attributes defensively.
  • DN escaping and search bases: Distinguished names contain commas, backslashes, and spaces. Use LdapRecord helpers where possible and avoid string-concatenating DNs.
  • No automatic Symfony security provider: Do not assume the bundle turns LDAP into a Symfony user provider. You will likely still need an authenticator, user provider, or login flow.
  • Long-running workers: Connections can go stale. Reconnect or recreate the connection in long-running consumers and scheduled jobs.
  • Error handling: Catch LdapRecord connection/auth exceptions and translate them into domain exceptions. Log bind failures without logging passwords.
  • Debugging: Symfony’s profiler will not show LDAP traffic. Enable LdapRecord logging or log around your service layer, and verify connectivity with command-line tools first.
  • Extension points: If the bundle’s services are too rigid, override service definitions, use a compiler pass, or bypass the bundle and register LdapRecord\Container/connections directly in services.yaml.
  • Still a thin-maintenance package: v4.0.0 lands the long-awaited LdapRecord v3 upgrade and namespace cleanup, but the project remains small. Pin ^4.0, watch for follow-up patches, and keep the option of wiring LdapRecord directly in services.yaml if the bundle lags again.
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.
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
robertmarney/lara-hierarchial-collections
simonschaufi/rule-doc-generator
emissaoja/emissaoja
blackbricksoftware/gravityforms-civicrm-form-processor
al-rahabi/fancy-crud
jinas/dhivatar-component
mltstephane/laravel-quality
bernskiold/laravel-talentlms
bernskioldmedia/laravel-form-architect