PHP+Active Directory. Сквозная авторизация и получение информации о пользователе из домена.
12.09.2016Здесь рассмотрим выполнение сквозной авторизации пользователя в Active Directory C получением параметров пользователя.
Необходимым условием является наличие пользователя в домене, т.е. пользователь не прописанный в домене не пройдет авторизацию.
Прежде всего необходимо установить соединение нашего php-скрипта с доменом.
Подразумевается, что в AD прописан не только пользователь, но и компьютер пользователя.
Часто в описании пользователя отсутсвует привязка к компьютеру, — этот скрипт проверяет сведения о компьтере в домене и вытягивает всю необходимую информацию.
Сделаем это следующим образом:
1. Получаем имя удаленного хоста, при входе пользователя на страницу.
$hostname = gethostbyaddr($_SERVER['REMOTE_ADDR']); //echo $hostname;
2. Поскольку полученное имя может быть длинее 15 символов (а именно столько позволяет внести NETBIOS-имя), — обрезаем до необходимой длнины, убираем все символы после первой точки (т.к. полученное имя имя будет иметь формат «логин.субдомен.домен») и в переменную «текущий пользователь» берем результат, добавляя к нему спецсимвол «$».
$hostname = substr($hostname, 0, 15); list($hostname,) = explode('.',$hostname); $cur_user=$hostname."$"; //echo $cur_user;
3. Устанавливаем соединение с доменом.
Для этого используем пару «логин-пароль» имеющие права считать информацию из AD.
$ds=ldap_connect("ldap-имя.домен"); // Необходимо указать корректный LDAP сервер ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3); // версия протокола зависит от настрое домена, в моем случае = 3 if ($ds) { $r=ldap_bind($ds, "логин@домен" ,"пароль"); // не анонимная привязка, /* тут выполняем операции по выборке данных из AD (описаны в пунктах 4 и 5) */ } else { echo "<h4>Невозможно подключиться к серверу LDAP</h4>"; }
Получение информации из домена разделим на две составляющие: информация о компьютере и информация о пользователе.
4. Извлечение информации о копьютере.
Эту операцию выполнит следующий код:
$sr=ldap_search($ds, "OU=ESRR, DC=esrr, DC=oao, DC=rzd", "samaccountname=".$cur_user); // живой пример $info = ldap_get_entries($ds, $sr); //print_r($info); // выведет всю доступную информацию, из которой и извлечем данные for ($i=0; $i&lt;$info["count"]; $i++) { $komp2000=iconv('utf-8', 'cp1251',$info[$i]["name"][0]); // имя компьютера в формате windows 2000 (соответсвует NETBIOS-имени) $dnsname=iconv('utf-8', 'cp1251',$info[$i]["dnshostname"][0]); // DNS-имя компьтера в домене. } //echo "Имя компа : ".$komp2000.""; //echo "Полный DNS компа : ".$dnsname.""; list($dnsname,) = explode('.',$dnsname); //echo "Краткий DNS компа : ".$dnsname.""; // В моем случае компьютеры записаны в домене в формате "префикс-имя компа", а пользователи - "префикс-имя пользователя", при этом имя компа = имя пользователя, поэтому выполняю операцию замены символа. $userlogin=str_replace('-','_',$dnsname); // получил логин $pref = explode("_", $userlogin); // получил префикс $upref = $pref[0]; // echo "pr : ".$upref."; //echo "Логин пользователя : ".$userlogin.";
5. Извлечение информации о пользователе (в качестве продолжения кода приведенного в п.4)
$sr2=ldap_search($ds, "OU=ESRR, DC=esrr, DC=oao, DC=rzd", "sAMAccountName=".mb_strtolower($userlogin));// живой пример // тут mb_strtolower - игнорирование регистра символов $info2 = ldap_get_entries($ds, $sr2); for ($i=0; $i&lt;$info2["count"]; $i++) { $fioful=iconv('utf-8', 'cp1251',$info2[$i]["cn"][0]); $company=iconv('utf-8', 'cp1251',$info2[$i]["company"][0]); } //echo "Полное имя пользователя : ".$fioful; //echo "Предприятие пользователя : ".$company;
Выше приведенный способ я использовал по причине запрета доменной политикой использования в браузере ActiveX.
Если же ActiveX у вас разрешен — можно использовать другой способ извлечения из AD информации о пользователе посетившем web-страницу, приведенный ниже:
I. Файл index.php
<script type="text/javascript"> var CurentUser = new ActiveXObject('WScript.Network'); var Param = CurentUser.UserName; document.write("<form name='FormU' method='post' action='auth.php'><input type='hidden' name='user' value='"+Param+"'></form>"); document.FormU.submit(); //отослали на траницу проверки авторизации </script>
II. Файл auth.php
$cur_user =$_REQUEST["user"]; $login=$cur_user; $ds=ldap_connect("esrr-dc-02.esrr.oao.rzd"); // Необходимо указать корректный LDAP сервер ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3); if ($ds) { $r=ldap_bind($ds, "логин@esrr.oao.rzd" ,"пароль"); // " не анонимная" привязка, $sr=ldap_search($ds, "OU=ESRR, DC=esrr, DC=oao, DC=rzd", "sAMAccountName=".mb_strtolower($login)); $info = ldap_get_entries($ds, $sr); for ($i=0; $i&lt;$info["count"]; $i++) { $fioful=iconv('utf-8', 'cp1251',$info[$i]["cn"][0]); $company=iconv('utf-8', 'cp1251',$info[$i]["company"][0]); $pref = explode("_", $cur_user); $upref = $pref[0]; $_SESSION['user_fio']=$fioful; // ФИО пользователя $_SESSION['user_d']=$login; // доменное имя пользователя $_SESSION['user_pred']=$company; // имя предприятия } // ЗДЕСЬ ПРОВЕРЯЕМ КАКОЕ-ЛИБО УСЛОВИЕ if ($stop == "1"){ header ("Location: ./error.php"); }else{ header ("Location: ./idx.php"); } // echo "Закрытие соединения"; ldap_close($ds); } else { echo "<h4>Невозможно подключиться к серверу LDAP</h4>"; }
Wikis are enabled by wiki software, otherwise known as wiki engines.
Добрый день. Поясните пожалуйста вот эту вашу фразу:»Подразумевается, что в AD прописан не только пользователь, но и компьютер пользователя.»
В АД в какие то дополнительный полы прописывается связка логин компьютер?
Если не трудно чирканите мне в почту. А то уже третий день бьюсь над аналогичной задачей но пока никуда не продвинулся.
по нормальному должен быть общий признак, но админы ленивы и редко делают такие связки
копм и юзер в AD заводятся отдельно
при наличии общего сделать связку в запросе легко
Данный метод кустарный и не несет никакой безопасности, т.к. клиент может передать серверу произвольный логин и имя компа. Где же тут обмен токенами?
» Где же тут обмен токенами»
—
зачем?
1. пользователь не должен иметь прав переименования компа или имени учетки…
2. имя компа вторично
3. юзер считывается с машины и сверяется с доменом
4. имя юзера должно быть = имени в домене.. + см пункт 1
Этого достаточно чтобы определить присутствие пользователя в домене и считать его параметры, и нет необходимости в токене при соблюдении всех условий
Небольшое дополнение к пункту 5:
Зачастую при вводе в домен, специалисты осуществляющие ввод ПК в AD не заморачиваются с длиной имени и правильностью написания, и получаются обрезанные имена. Чтобы учесть этот момент — следует в 1 первой строке примера произвести изменения.
заменить на