Php доменная авторизация. Зависимости, вспомогательные функции

In this section, you"ll learn how to search and retrieve data from the directory server, as well as add, modify, and delete entries.

ldap_search()

resource ldap_search (resource link_identifier, string base_dn, string filter [, array attributes [, int attrsonly [, int sizelimit [, int timelimit [, int deref]]]]])
The ldap_search() function offers a powerful means for searching the directory server pointed to by link_identifier. It will search to a depth of LDAP_SCOPE_SUBTREE, a value that can be set via the previously introduced function ldap_set_option(). By default, this value is set to search to an infinite depth, or through the entire scope of the tree as defined by the base_dn. The search filter, equivalent to a relational database query, is passed in via the filter parameter. Finally, you can specify exactly which attributes should be returned within the search results via the attributes parameter. The remaining four parameters are optional, and therefore in the interests of space, I"ll leave it as an exercise to you to learn more about them. Let"s consider an example:

"; } ldap_unbind($ad); ?> A sampling of the results follow: Gilmore, Jason (Columbus) Shoberg, Jon (Columbus) Streicher, Martin (San Francisco) Wade, Matt (Orlando)

Most of this is likely straightforward, save for the potentially odd way in which attribute values are referenced. All attribute rows are ultimately multi-dimensional arrays, with each attribute value referenced by a combination of row number, attribute name, and attribute array index. So, for example, even attributes such as "sn", the attribute name for the user"s last name, is an indexed array.

ldap_mod_add()

boolean ldap_mod_add(resource link_id, string dn, array entry)
Adding entries to the directory server is accomplished via the ldap_mod_add() function. A new entry is added simply by creating an array consisting of the attribute/value mappings intended to comprise the new row. This process is perhaps best explained with an example:

As is the case with all directory server tasks, be sure that the binding user has proper permissions to add the target data; otherwise, errors will occur.

ldap_mod_replace()

boolean ldap_mod_replace(resource link_id, string dn, array entry)
Modifying entry attributes is accomplished via the ldap_mod_replace() function. It operates exactly like ldap_add(), save for the added step of identifying the entry you"d like to modify. This is done by pointing to a very specific dn. Like ldap_add(), both a valid link identifier and an array consisting of the entries you"d like to update must be provided. An example follows, demonstrating how a user"s telephone number would be modified. In particular, take note of the very specific DN (pointing to my particular entry).

As is the case with all directory server tasks, be sure that the binding user has proper permissions to modify the target data; otherwise, unexpected errors will occur.

ldap_delete()

boolean ldap_delete(resource link_id, string dn)
Rounding out our survey of key PHP LDAP functions is ldap_delete(). This function is used to delete an existing entry. Like ldap_mod_replace(), a very specific DN must be provided to effect the deletion. The following example demonstrates how to remove the "Jason Gilmore" user entry from Active Directory:

As is the case with all directory server tasks, be sure that the binding user has proper permissions to delete the target data; otherwise, unexpected errors will occur.

Searching Active Directory via the Web

I always like to round out a tutorial with an applicable example that readers can immediately adapt to their own needs. In this tutorial, I"ll show you how to create a search interface capable of searching by name, location, or phone number. All you"ll need to do is modify the connection variables and base DN. To begin, let"s create the search interface, which will be saved as "search.html":

Search criteria:

Filter:

Figure 1 offers an example of what this search form would look like in the browser.

Figure 1. The Active Directory Search Form

Next, we"ll need to create the logic that effects the search. This short bit of code is shown here:

0) { for ($i=0; $i<$entries["count"]; $i++) { echo "

Name: ".$entries[$i]["displayname"]."
"; echo "Phone: ".$entries[$i]["telephonenumber"]."
"; echo "Email: ".$entries[$i]["mail"]."

"; } } else { echo "

No results found!

"; } ldap_unbind($ad); ?>

You can either change the action destination specified in the search interface, pointing it to a file consisting of the above script, or you can bundle it into the same file as the search interface, and use isset() and an if conditional to trigger execution in the case that the search submit button is depressed. Of course, you"ll want to add some additional data validation criteria prior to deploying such a script. Figure 2 offers a sampling of the search results.

Figure 2. Search Results

Conclusion

Although PHP has long been my primary language for developing Web applications, I"ve found Perl to be an integral part of my programmer"s toolkit. When working with directory servers, this sentiment is no different. Therefore, the next article is devoted to Perl/LDAP basics. As was the case with this article, all examples are specific to Microsoft"s Active Directory, although you should be able to easily apply them to any directory server implementation. We"ll round out that article with an example demonstrating how to create statically cached Web-based user directories using a Perl script and CRON (or Windows Task Scheduler).

I welcome questions and comments! E-mail me at [email protected] . I"d also like to hear more about your experiences integrating Microsoft and Open Source technologies!

About the Author

W. Jason Gilmore (http://www.wjgilmore.com/) is an Internet application developer for the Fisher College of Business. He"s the author of the upcoming book, PHP 5 and MySQL: Novice to Pro, due out by Apress in 2004. His work has been featured within many of the computing industry"s leading publications, including Linux Magazine, O"Reillynet, Devshed, Zend.com, and Webreview. Jason is also the author of A Programmer"s Introduction to PHP 4.0 (453pp., Apress). Along with colleague Jon Shoberg, he"s co-author of "Out in the Open," a monthly column published within Linux magazine.

IT Solutions Builder TOP IT RESOURCES TO MOVE YOUR BUSINESS FORWARD

Drupal можно с легкостью назвать универсальным инструментом для реализации различных задач, также и определенной сложности enterprise решения.
Так получилось, что в основном Drupal я использую на предприятии, внутри Интранет сети, которая имеет Active Directory . И для того чтобы полноценно
использовать инфраструктура нашей сети, программой минимум это является Active Directory авторизация на сайтах и сервисах, и тут проблем у Drupal-а
нет, благодаря модулю Lightweight Directory Access Protocol (LDAP) .
В данном материале я хочу рассказать, как он настроен в моём окружении, и может кому то статья пригодится.

Итак, сразу забегая скажу, что с помощью данного модуля вы сможете предоставить:
1. LDAP авторизацию в вашей сети (в моём случае используется Active Directory от Microsoft)
2. Настроить сквозную авторизацию (когда пользователь автоматически входит под учётной записью операционной системы)
3. Ограничивать доступ, тем кто может входить на сайт и кому нельзя.
4. Синхронизация атрибутов учетной записи Active Directory с полями профиля пользователя на сайте, так и наоборот.
5. Актуализация учетной записи на сайте после смены логина учетной записи Active Directory (обычно происходит после смены фамилии сотрудника - меняется аналогично логин)
6. Присваивание роли пользователю на сайте в зависимости от его нахождения в определенной группе Active Directory

Т.к. я пока являюсь активным пользователем Drupal 7, то все инструкции буду приводить на его примере, но опять же когда я интереса ради запускал Drupal 8,
то понял что модуль практически идентичен 7ой версии Drupal.

Скопируем к себе данные модуля, а также их зависимости Ctools и Entity API . На странице модулей активируем следующие модули:

  1. LDAP Authentication
  2. LDAP Authorization (модуль опционально, если вам требуется ограничение на доступ к сайта, либо ролям сайта по признаку нахождения пользователя в группах Active Directory)
  3. LDAP Authorization - Drupal Roles (дополнение к выше описанному модулю)
  4. LDAP Servers
  5. LDAP SSO (модуль опционально, если вам не требуется сквозная авторизация, либо пока веб-сервер не настроен под это, можно не устанавливать)
  6. LDAP User Module

Стоит отметить, что модуль не установится, если в ваших настройках PHP не установлен модуль php_ldap . Потому заранее установите, и настройте под характеристики вашего окружения.

После успешной установки модуля, перейдем в его настройки которые расположены здесь admin/config/people/ldap

Настройки модуля поделены на 4 вкладки: Settings , Servers , User , Authentication , Authorization

В первой вкладке настраивается метод шифрования паролей учетной записи Active Directory внутри Drupal-а.

На своей практике я это не использую, потому сразу перехожу во вторую вкладку Servers . И здесь мы остановимся по подробней.
Во вкладке отображены все созданные сервера LDAP авторизации, которые будут использованы на сайте, по умолчанию этот список пуст и нам с помощью кнопки Add LDAP Server Configuration можно создать новый сервер.
Страница создания сервера поделена на несколько блоков, рассмотрим каждый из них:

Connection settings

Machine name for this server configuration . - собственно машинное имя создаваемого сервера. Обычно называю active_directory
Name **- ещё какое то имя сервера, также называю active_directory
**Enabled
- ставлю галочку, таким образом включаю создаваемую конфигурацию сервера
LDAP Server Type - в моём случае выбираю Active Directory
LDAP server - доменное имя либо IP адрес по которому находится сервер Active directory, в моём случае ad.zv
LDAP port - отставляю по умолчанию 389 , у нас он такой же
Use Start-TLS - галочку не ставлю, т.к. не используем шифрование
Follow LDAP Referrals - также не ставлю, хотя так до конца и не разбирался для чего нужна данная настройка

Bingind method

Binding Method for Searches (such as finding user object or their group memberships)
Другими словами спрашивается каким образом, от чьего имени будет происходить подключение к сервере Active directory для поиска пользователя на факт существования, чтения его аттрибутов и т.д.
Также как и в описании к значения использую первый вариант Service Account Bind как best practice.
А именно подключение к серверу будет происходить от специальной заранее созданной учетной записи в Active directory которая имеет право на чтение каталогов и структуры Active Directory
Выбирая данный вариант ниже необходимо указать логин и пароль сервисной учетной записи в полях DN for non-anonymous search и Password for non-anonymous search

Clear existing password from database. Check this when switching away from Service Account Binding - пункт не применим к нашему методу описанному выше, потому галочку не ставим.

LDAP user to Drupal user relationship

Base DNs for LDAP users, groups, and other entries - базовый DN где находятся все пользователи в Active Directory, в моём случае ставлю DC=ad,DC=zv . В данной настройке лучше проконсультироваться с системными администраторами вашего сервера Active Directory
AuthName attribute и AccountName attribute - атрибут в котором хранится логин пользователя и аккаунт имя, обычно они должны быть одинаковы, и в большинстве случаев указывается samaccountname , т.к. по умолчанию логин находится там в Active Directory
Email attribute - атрибут в котором находится почтовый ящик пользователя, в моём случае mail . Стоит отметить что для Drupal-а это поле обязательно, т.к. Drupal не может иметь пользователя без почтового ящика, потому если в вашем окружении есть вероятность того что существует пользователи без почтового ящика, то вам необходимо воспользоваться полем ниже для заполнения почтового ящика по шаблону, либо позже в другой вкладке мы вернёмся к данной настройке с другой стороны.
Email template - шаблон почтового ящик, применяется тогда, когда ваши почтовые ящики например идентичны логину, либо состоят из нескольких атрибутов пользователя в Active Directory. Потому вы может просто составить его из токенов аттрибутов.
Thumbnail attribute - атрибут в котором находится изображение пользователя (в binary) для последующей загрузки в изображения профиль пользователя в Drupal-е, в моём случае thumbnailPhoto
Persistent and Unique User ID Attribute - уникальный атрибут, который никогда не изменится у пользователя Active Directrory. Применяется в тех случаях когда например логин у вас представляет собой фамилию и инициалы пользователя, и если вдруг пользователь сменил фамилию, и следом ему изменили логин, то для следующего входа им на сайт для Drupal-а он будет по умолчанию как новый пользователь, и Drupal будет создавать новую учётную запись (конечно при условии, что почтовый ящик ему тоже сменили, т.к. если он останется прежним, то Drupal сообщит о конфликте почтового ящика, и не создаст новую запись). Именно поэтому данное поле служит уникальным ключом на которое в первую очередь будет смотреться при входе пользователя на сайт, даже если он сменил логин, Drupal сначала найдёт его по данному атрибуты, и тогда по нему построит связь с пользователем Active Directory и как следствие обновит ему логин на сайте Drupal. В моем случае это objectsid
Does the Persistent and Unique User ID Attribute hold a binary value? - галочку ставлю, т.к. objectsid хранится в binary.

Никогда не думал, что столкнусь с такой задачей, тем не в один прекрасный день возникла необходимость создать корпоративный портал для внутреннего использования. В организации есть домен и куча пользователей в этом домене. Было бы безусловно круто не плодить сущности (не создавать заново учетки для пользователей), а как-то привязаться к домену.

Сначала был долгий мозговой штурм и решали на чем делать этот портал - то ли вручную на PHP или ASP, то ли использовать какой-то готовый узкоспециализированный продукт и использовать его. При том, что этот продукт должен быть бесплатным. Естественно, никакого вменяемого бесплатного решения именно для корпоративного портала не нашлось, а писать все это вручную не было особого желания, возникла мысль - "а может Joomla?"

Сначала эту идею пытались закопать, ибо "не круто" но чем дальше обсуждали, тем больше чаша весов склонялась в пользу Joomla. Проверенного, распространенного и абсолютно бесплатного. Осталось решить только одно - как подружить Joomla с Active Directory. Оказалось, это возможно, хотя пришлось немного повозиться.

Я не буду расписывать такие простые истины, например, как установить Joomla на локальный хост и прочее, сразу к делу.

1 этап - правка файла PHP.ini

Нужно раскомментировать строчку:

extension=php_ldap.dll

Это библиотека, благодаря которой возможно взаимодействие Joomla с доменом Active Directory по протоколу LDAP.

2 этап - настройка плагина "Авторизация LDAP"

Идем в менеджер плагинов и ищем среди них "Авторизация LDAP", активируем его.

Предположим, что домен у нас называется domain.local, адрес контроллера домена - 192.168.0.1.

В настройках плагина нужно сделать следующие настройки (по крайней мере, у меня так заработало:)

Параметр Значение Комментарий
Хост 192.168.0.1 IP-адрес контроллера домена
Порт 389 не трогаем
Выполнять LDAP3 ДА
Выполнять TLS НЕТ
Следовать перенаправлениям НЕТ
Метод авторизации Привязать и найти При успешной авторизации Joomla создаст свою внутреннюю учетку, которую можно будет потом поместить в ту или иную группу доступа. К сожалению, группы пользователей из Active Directory Joomla подтягивать не умеет. Если нашли способ сделать это, поделитесь в комментариях к статье!
Базовый DN dc=domain,dc=local Разделяем домен на уровни и перед каждым уровнем пишем dc=..., между ними никаких пробелов, только запятые
Строка поиска sAMAccountName= Регистр имеет значение!
Пользовательский DN оставляем пустым
Имя пользователя подлючения Этот адрес электронной почты защищён от спам-ботов. У вас должен быть включен JavaScript для просмотра. Имя доменного администратора
Пароль подключения qwerty123 Соответственно, пароль доменного администратора
Map: Full Name displayName То, как на сайте будет высвечиваться имя пользователя
Map: Email mail то же самое - емэйл
Map: User ID uid идентификатор пользователя

Сохраняем настройки, открываем сайт и пытаемся залогиниться. При этом вводить имя доменного пользователя указываем без @domain.local - все должно заработать!

Подозреваю, что многие нюансы зависят от версий программного обеспечения. На всякий случай, все это тестировалось на следующем сервере:

  • Веб-сервер - Xampp 5.6.15 (PHP 5.6.15)
  • Joomla 3.6.3
  • Контроллер домена Windows Server 2008 R2

добавлено 26.10.2016

Замечена странность - Joomla не хочет авторизовать пользователей, чей логин в домене не совпадает с адресом электронной почты в Exchange. При попытке авторизации выдается сообщение об ошибке:

Предупреждение

У вас нет права доступа к закрытой части сайта.

Решение данной проблемы пока не найдено. Если вы знаете, как это преодолеть, пожалуйста, поделитесь в комментариях.