Настройка логина через LDAP в Symfony2

Я не буду рассказывать подробно как настроить, так как это есть в документации. Расскажу только историю о том, как я из-за невнимательности долго не мог его настроить и какие подводные камни могут ожидать тех, кто еще не подключал LDAP в Symfony.

Дано

LDAP сервер на Windows
Symfony2 project на Debian

Требуется

Осуществить вход в учётные записи по средствам LDAP. Грубо говоря, использовать для авторизации тот же логин и пароль, которым вы входите на ваш рабочий компьютер.

Действую

После поисков подходящей реализации для Symfony, остановился на бандле французского разработчика Boris Morel. Который даже оказывал мне помощь в настройке. Symfony community is the best.

Ldap Bundle

https://packagist.org/packages/imag/ldap-bundle

В принципе ознакомившись с readme.md файлом можно всё настроить, если ничего не пропустить.
https://github.com/BorisMorel/LdapBundle/blob/master/README.md

Но лично у меня были проблемы с тем, что я вводил правильные данные, а выдавало Bad credentials, а почему не ясно.

Борис Морель подсказал мне параметр для security.yml конфигурации:
hide_user_not_found: false

После этого вместо Bad credentials я стал получать более внятные ошибки конкретно от LDAP сервиса.
И я уже знал, что мой symfony сервер присоединился к LDAP серверу, если я набираю ему свой логин aharbunou (существующий), говорит The presented password is invalid, а если набирал что-то отличное от своего логина, то There is no user with name “blablabla”.
Радовало, что хоть пользователя видит.

Оказалось, что по невнимательности я пропустил параметр внутри настроек firewalls.

 imag_ldap:
     provider: multiples

И когда мой security.yml стал выглядеть таким образом

security:
    hide_user_not_found: false
    firewalls:
        restricted_area:
            form_login:
                  check_path: /login_check
                  login_path: /login
                  always_use_default_target_path: true
                  default_target_path: /
                  csrf_provider: form.csrf_provider
                  intention: authenticate
                  provider: ldap
            pattern:          ^/
            anonymous:        ~
            imag_ldap:
                provider: multiples

            logout:
              path:   /logout
              target: /
              invalidate_session: false
    providers:
        multiples:
            chain:
                providers: [ ldap, memory ]
        ldap:
            id: imag_ldap.security.user.provider
        memory:
          memory:
            users:
              demo:
                password:           demo
                roles:              ROLE_USER
              admin:
                password:           admin
                roles:              [ROLE_USER, ROLE_ADMIN]


    encoders:
        IMAG\LdapBundle\User\LdapUser: plaintext
        Symfony\Component\Security\Core\User\User: plaintext

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

imag_ldap:
  client:
    host: ARTGROUP.local
    port: 389
    username: ARTGROUP\aharbunou #change to your login with access to group
    password: ********* #change to your password
    version: 3
    referrals_enabled: false
    bind_username_before: false
    skip_roles: true

  user:
    base_dn: CN=Users,DC=ARTGROUP,DC=local
    name_attribute: sAMAccountName # or uid

то сообщение при неправильном логине выводилось The LDAP authentication failed.

В моем примере используется цепочка security providers, на случай если LDAP сервер недоступен, чтобы стандартный пользователь или админ брался из памяти.
Роли здесь не настроены, а только сам вход. По завершению отладки многие параметры можно удалить, но я демонстрирую весь конфиг, чтобы наглядно было, что включено, а что нет.
Свой security provider создавать не обязательно, так же как и entity User.php тоже не нужен. К чему всё усложнять, если из директории vendors берутся нужные универсальные коды.

Для ручного соединения с LDAP использовался LDAPAdmin.