Аутентификация в PHP с использованием LDAP через Active Directory

104

Я ищу способ аутентификации пользователей через LDAP с PHP (с Active Directory в качестве провайдера). В идеале он должен работать на IIS 7 ( adLDAP делает это на Apache). Кто-нибудь делал что-то подобное, но успешно?

  • Изменить: я бы предпочел библиотеку / класс с кодом, готовым к работе ... Было бы глупо изобретать колесо, когда кто-то уже это сделал.
DV.
источник
Я думаю, что у drupal есть модуль для этого
redben

Ответы:

167

Импорт всей библиотеки кажется неэффективным, когда все, что вам нужно, это две строчки кода ...

$ldap = ldap_connect("ldap.example.com");
if ($bind = ldap_bind($ldap, $_POST['username'], $_POST['password'])) {
  // log them in!
} else {
  // error message
}
Ceejayoz
источник
43
Некоторые установки AD успешно связываются, если введенный пароль пуст. Остерегайтесь этого! Возможно, вам потребуется убедиться, что пароль не пустой, перед попыткой аутентификации.
diolemo
@diolemo Есть ли способ предотвратить это, не проверяя, пуст ли пароль?
Нафтали, он же Нил,
@Neal Вы можете использовать, ldap_set_optionчтобы заставить его вести себя по-другому. Возможно установка версии протокола? Придется поэкспериментировать. Я бы лично посоветовал вам все равно проверить пустой пароль на всякий случай.
diolemo
@diolemo Я
Нафтали, он же Нил,
Анонимному редактору: нет, насколько мне известно, дезинфекция ввода здесь не требуется, поскольку ldap_bindона обрабатывается, и специальные символы не являются проблемой.
ceejayoz 08
14

Вы можете подумать, что простая аутентификация пользователя в Active Directory будет довольно простым процессом с использованием LDAP в PHP без необходимости в библиотеке. Но есть много вещей, которые могут очень быстро усложнить задачу:

  • Вы должны подтвердить ввод. В противном случае прошло бы пустое имя пользователя / пароль.
  • Вы должны убедиться, что имя пользователя / пароль правильно закодированы при привязке.
  • Вы должны шифровать соединение с помощью TLS.
  • Использование отдельных серверов LDAP для резервирования в случае отказа одного из них.
  • Получение информативного сообщения об ошибке в случае сбоя аутентификации.

На самом деле в большинстве случаев проще использовать библиотеку LDAP, поддерживающую вышеуказанное. В конечном итоге я создал свою собственную библиотеку, которая обрабатывает все вышеперечисленные пункты: LdapTools (ну, не только для аутентификации, он может гораздо больше). Его можно использовать следующим образом:

use LdapTools\Configuration;
use LdapTools\DomainConfiguration;
use LdapTools\LdapManager;

$domain = (new DomainConfiguration('example.com'))
    ->setUsername('username') # A separate AD service account used by your app
    ->setPassword('password')
    ->setServers(['dc1', 'dc2', 'dc3'])
    ->setUseTls(true);
$config = new Configuration($domain);
$ldap = new LdapManager($config);

if (!$ldap->authenticate($username, $password, $message)) {
    echo "Error: $message";
} else {
    // Do something...
}

Вызов аутентификации выше будет:

  • Убедитесь, что ни имя пользователя, ни пароль не пусты.
  • Убедитесь, что имя пользователя и пароль правильно закодированы (по умолчанию UTF-8)
  • Попробуйте использовать альтернативный сервер LDAP, если он не работает.
  • Зашифруйте запрос аутентификации с помощью TLS.
  • Предоставьте дополнительную информацию, если это не удалось (например, заблокированная / отключенная учетная запись и т. Д.)

Для этого существуют и другие библиотеки (например, Adldap2). Тем не менее, я чувствовал себя достаточно вынужденным предоставить некоторую дополнительную информацию, поскольку ответ, получивший наибольшее количество голосов, на самом деле представляет собой угрозу безопасности, на которую можно полагаться, без проверки ввода и без использования TLS.

ЧадСикорра
источник
1
Для соединений LDAP TLS устарел в пользу StartTLS: openldap.org/faq/data/cache/605.html .
zenlord
2
@zenlord Использование ldaps://формата для подключения устарело. В моем примере, когда вы указываете, setUseTls(true)он использует ldap://формат, а затем выдает StartTLS с использованием ldap_start_tls($connection). Таким образом, сам TLS не устарел, просто используется подключение ldaps://(которое фактически подключается к LDAP через совершенно другой порт).
ChadSikorra
12

Я делаю это, просто передавая учетные данные пользователя ldap_bind ().

http://php.net/manual/en/function.ldap-bind.php

Если учетная запись может быть привязана к LDAP, это действительно так; если не может, то нет. Если все, что вы делаете, это проверка подлинности (а не управление учетной записью), я не вижу необходимости в библиотеке.

Скотт Рейнен
источник
9

Мне нравится класс Zend_Ldap , вы можете использовать только этот класс в своем проекте без Zend Framework.

CMS
источник
1
Я столкнулся с трудностями при реализации вышеизложенного, чтобы обнаружить, что это было для управления без аутентификации. Я собираюсь перейти на zend.auth.adapter.ldap
vdidxho