Developed with love by KnpLabs Hire us for your project!
111

LdapBundle

by BorisMorel

This bundle is autonomous ; He doesn't require "apache mod_ldap"

LdapBundle

LdapBundle provides LDAP authentication without using Apache's mod_ldap. The bundle instead relies on PHP's LDAP extension along with a form to authenticate users. LdapBundle can also be used for authorization by retrieving the user's roles defined in LDAP.

Contact

Nick: aways
IRC: irc.freenode.net - #symfony-fr

Install

  1. Download with composer
  2. Enable the Bundle
  3. Configure LdapBundle in security.yml
  4. Import LdapBundle routing
  5. Implement Logout
  6. Use chain provider
  7. Subscribe to PRE_BIND event
  8. Subscribe to POST_BIND event

Get the Bundle

Composer

Add LdapBundle in your project's composer.json

{
    "require": {
        "imag/ldap-bundle": "dev-master"
    }
}

Enable the Bundle

<?php
// app/AppKernel.php

public function registerBundles()
{
    $bundles = array(
        // ...
        new IMAG\LdapBundle\IMAGLdapBundle(),
    );
}

Configure security.yml

Note:

An example security.yml file is located within the bundle at ./Resources/Docs/security.yml

# ./IMAG/LdapBundle/Resources/config/security.yml

security:
  firewalls:
    restricted_area:
      pattern:          ^/
      anonymous:        ~
      provider:         ldap
      imag_ldap:        ~
      # alternative configuration
      # imag_ldap:
      #   login_path:   /ninja/login
      logout:
        path:           /logout
        target:         /

  providers:
    ldap:
      id: imag_ldap.security.user.provider

  encoders:
    IMAG\LdapBundle\User\LdapUser: plaintext

  access_control:
    - { path: ^/login,          roles: IS_AUTHENTICATED_ANONYMOUSLY }
    - { path: ^/,               roles: IS_AUTHENTICATED_FULLY }

imag_ldap:
  client:
    host: your.host.foo
    port: 389
#    version: 3 # Optional
#    username: foo # Optional
#    password: bar # Optional
#    network_timeout: 10 # Optional
#    referrals_enabled: true # Optional
#    bind_username_before: true # Optional
#    skip_roles: false # Optional

  user:
    base_dn: ou=people,dc=host,dc=foo
#    filter: (&(foo=bar)(ObjectClass=Person)) #Optional
    name_attribute: uid
  role:
    base_dn: ou=group, dc=host, dc=foo
#    filter: (ou=group) #Optional
    name_attribute: cn
    user_attribute: member
    user_id: [ dn or username ]

#  user_class: IMAG\LdapBundle\User\LdapUser # Optional

You should configure the parameters under the imag_ldap section to match your environment.

Note:

The optional parameters have default values if not set.
You can disable default values by setting a parameter to NULL.

# app/config/security.yml
imag_ldap:
  # ...
  role:
    # ...
    filter: NULL

Import routing

# app/config/routing.yml

imag_ldap:
  resource: "@IMAGLdapBundle/Resources/config/routing.yml"

Implement Logout

Just create a link with a logout target.

<a href="{{ path('logout') }}">Logout</a>

Note:

You can refer to the official Symfony documentation :
http://symfony.com/doc/current/book/security.html#logging-out

Chain provider

You can also chain the login form with other providers, such as database_provider, in_memory provider, etc.

# app/config/security.yml
security:
    firewalls:
        secured_area:
            pattern: ^/
            anonymous: ~
            imag_ldap:
                provider: multiples
            logout:
                path: logout
    providers:
        multiples:
            chain:
                providers: [ldap, db]          
        ldap:
            id: imag_ldap.security.user.provider
        db:
            entity: { class: FQDN\User }

Note:

If you have set the config option bind_username_before: true you must chain the providers with the ldap provider in the last position.

# app/config/security.yml

providers: [db, ldap]          

Subscribe to PRE_BIND event

The PRE_BIND is fired before the user is authenticated via LDAP. Here you can write a listener to perform your own logic before the user is bound/authenticated to LDAP.
For example, to add your own roles or do other authentication/authorization checks with your application.

If you want to break the authentication process within your listener, throw an Exception.

Example listener:
xml
<service id="ldap.listener" class="Acme\HelloBundle\EventListener\LdapSecuritySubscriber">
<tag name="kernel.event_subscriber" />
</service>

Example:
```php
<?php

namespace Acme\HelloBundle\EventListener;

use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use IMAG\LdapBundle\Event\LdapUserEvent;

/**
* Performs logic before the user is found to LDAP
*/
class LdapSecuritySubscriber implements EventSubscriberInterface
{
public static function getSubscribedEvents()
{
return array(
\IMAG\LdapBundle\Event\LdapEvents::PRE_BIND => 'onPreBind',
);
}

/**
 * Modifies the User before binding data from LDAP
 *
 * @param \IMAG\LdapBundle\Event\LdapUserEvent $event
 */
public function onPreBind(LdapUserEvent $event)
{
    $user = $event->getUser();
    $config = $this->appContext->getConfig();

    $ldapConf = $config['ldap'];

    if (!in_array($user->getUsername(), $ldapConf['allowed'])) {
        throw new \Exception(sprintf('LDAP user %s not allowed', $user->getUsername()));
    }

    $user->addRole('ROLE_LDAP');
    $event->setUser($user);
}

}
```

Subscribe to POST_BIND event

The POST_BIND is fired after the user is authenticated via LDAP. You can use it in exactly the same manner as PRE_BIND.

Note:

However each time a page is refreshed, Symfony call the refreshUser method in the provider that is used and doesn't trigger these events (PRE_BIND and POST_BIND).
If you want to override user (for example like credentials, roles ...), you must create a new provider and override this method.

imag_ldap:
client: # Required
host: ~ # Required
port: 389
version: ~
username: ~
password: ~
bind_username_before: false
referrals_enabled: ~
network_timeout: ~
skip_roles: false
user: # Required
base_dn: ~ # Required
filter: ~
name_attribute: uid
attributes: Array
role:
base_dn: ~ # Required
filter: ~
name_attribute: cn
user_attribute: member
user_id: dn
user_class: IMAG\LdapBundle\User\LdapUser
  • Merge pull request #137 from artembasnev/slugify_unicode
    By BorisMorel, 2 years ago
  • Updates slugify function to support unicode
    By , 2 years ago
  • Fix #134 and Fix PSR-2
    By BorisMorel, 2 years ago
  • Merge pull request #123 from bobman38/patch-1
    By BorisMorel, 2 years ago
  • add getCn/setCn on User Entity
    By , 2 years ago
  • Fix #122
    By BorisMorel, 3 years ago
  • Exception throw
    By BorisMorel, 3 years ago
  • Merge branch 'master' of git://github.com/Warbo/LdapBundle into Warbo-master
    By BorisMorel, 3 years ago
  • Merge branch 'FabienSalles-master'
    By BorisMorel, 3 years ago
  • Merge branch 'master' of git://github.com/FabienSalles/LdapBundle into FabienSalles-master
    By BorisMorel, 3 years ago
  • Improve checkLdapError with the new fct getError() getErrno()
    By BorisMorel, 3 years ago
  • Add the new mandatories functions
    By BorisMorel, 3 years ago
  • Fix regression bug with skip_roles
    By BorisMorel, 3 years ago
  • Merge branch 'master' of git://github.com/oleg-andreyev/LdapBundle into oleg-andreyev-master
    By BorisMorel, 3 years ago
  • addressing PR comments: added ability to pass Resource to getError and getErrno
    By Oleg Andreyev, 3 years ago
  • Improve the error recovered ; Fix #120
    By BorisMorel, 3 years ago
  • Merge branch 'NikolaySl-throw_exception_on_ldap_error'
    By BorisMorel, 3 years ago
  • Merge branch 'throw_exception_on_ldap_error' of git://github.com/NikolaySl/LdapBundle into NikolaySl-throw_exception_on_ldap_error
    By BorisMorel, 3 years ago
  • Fix #121 and #95
    By BorisMorel, 3 years ago
  • Make LdapConnect throw ConnectionException if ldap server returns error. LdapAuthenticationProvider converts ConnectionException to AuthenticationException.
    By Nikolay Slyunkov, 3 years ago
  • adding ldap_errno and ldap_error, useful for debugging and more verbose error message
    By Oleg Andreyev, 3 years ago
  • fix typo
    By FabienSalles, 3 years ago
  • improve documentation
    By FabienSalles, 3 years ago
  • Added a $userEvent back, since $user may be updated
    By Chris Warburton, 3 years ago
  • Pulled $userEvent out of 'if' branches
    By Chris Warburton, 3 years ago
  • Merge pull request #105 from iltar/master
    By BorisMorel, 3 years ago
  • Fixed a typo from a previous commit
    By iltar, 3 years ago
  • Merge branch 'master' of git://github.com/BorisMorel/LdapBundle
    By BorisMorel, 3 years ago
  • Fix typo
    By BorisMorel, 3 years ago
  • Remove LdapToken to increase compatibiliti
    By BorisMorel, 3 years ago