Как отфильтровать информацию о пользователях Active Directory ldap на основе аутентификации Windows IIS и отобразить эту информацию на сайте php? - PullRequest
0 голосов
/ 07 октября 2019

Я создаю интранет-сайт PHP без каких-либо требований для входа. У меня есть приложение IIS (на основе PHP), проверка подлинности выполняется с помощью проверки подлинности Windows (анонимная проверка подлинности отключена). Мне удалось настроить IIS и проверку подлинности Windows с помощью некоторых настроек GPO. Моя простая страница PHP содержит $_SERVER['REMOTE_USER'];, поэтому активный пользователь каталога без каких-либо приглашений может видеть DOMAIN \ User.Name

В моем понимании проверка подлинности IIS в Windows очень ограничена и может отображать только имя пользователя и имя домена. Поэтому я включил LDAP для отображения дополнительной информации о пользователе, такой как отображаемое имя или номер телефона. Но я застрял здесь, потому что, насколько я знаю, LDAP использует привязку имени пользователя и пароля для получения информации. Когда я использую учетные данные администратора Active Directory, он дает мне таблицу всей информации о пользователе, но как отфильтровать эту таблицу для отображения только текущей информации о пользователе (на основе аутентификации Windows).

Код:

<?php
$current_user = get_current_user();
$ldap_password = 'AdminPassword';
$ldap_username = 'Administrator@domain.name';
$ldap_connection = ldap_connect("domain.name");

if (FALSE === $ldap_connection){
    echo 'ERROR';
}

ldap_set_option($ldap_connection, LDAP_OPT_PROTOCOL_VERSION, 3) or die('Unable to set LDAP protocol version');
ldap_set_option($ldap_connection, LDAP_OPT_REFERRALS, 0); 

if (TRUE === ldap_bind($ldap_connection, $ldap_username, $ldap_password)){

    $ldap_base_dn = 'OU=Users,DC=domain,DC=name';

    $search_filter = '(|(objectCategory=person)(objectCategory=contact))';

    $result = ldap_search($ldap_connection, $ldap_base_dn, $search_filter);

    if (FALSE !== $result){
        $entries = ldap_get_entries($ldap_connection, $result);

        echo '<h2>Result</h2></br>';
        echo '<table border = "1"><tr><td>Username</td><td>Last Name</td><td>First Name</td></tr>';

        for ($x=0; $x<$entries['count']; $x++){

            $LDAP_samaccountname = "";

            if (!empty($entries[$x]['samaccountname'][0])) {
                $LDAP_samaccountname = $entries[$x]['samaccountname'][0];
                if ($LDAP_samaccountname == "NULL"){
                    $LDAP_samaccountname= "";
                }
            } else {

                $LDAP_uSNCreated = $entries[$x]['usncreated'][0];
                $LDAP_samaccountname= "CONTACT_" . $LDAP_uSNCreated;
            }

            //Last Name
            $LDAP_LastName = "";

            if (!empty($entries[$x]['sn'][0])) {
                $LDAP_LastName = $entries[$x]['sn'][0];
                if ($LDAP_LastName == "NULL"){
                    $LDAP_LastName = "";
                }
            }

            //First Name
            $LDAP_FirstName = "";

            if (!empty($entries[$x]['givenname'][0])) {
                $LDAP_FirstName = $entries[$x]['givenname'][0];
                if ($LDAP_FirstName == "NULL"){
                    $LDAP_FirstName = "";
                }
            }

            echo "<tr><td><strong>" . $LDAP_samaccountname ."</strong></td><td>" .$LDAP_LastName."</td><td>".$LDAP_FirstName."</td></tr>";


        }
    }

    ldap_unbind($ldap_connection);
    echo("</table>");
}
?>

EDIT : удалось отфильтровать текущего пользователя путем редактирования фильтра LDAP:

$search_filter = "(|(objectCategory=persons)(sAMAccountName=*$current_user*))";

1 Ответ

1 голос
/ 07 октября 2019

Ваш запрос почти прав, но он работает окольным путем:)

Нет objectCategory с именем persons. Это просто person (без «с»). Так что objectCategory=persons всегда ложно для каждого объекта в вашем домене. Но это работает, потому что вы используете ИЛИ (|).

Так что единственный критерий, который он действительно использует, это sAMAccountName=*$current_user*. Но это требует любого объекта, в котором sAMAccountName содержит $current_user. Это имеет два непреднамеренных последствия:

  1. Если у вас есть пользователь с именем neil, а другой - с именем oneil, то всякий раз, когда neil входит в систему, вы найдете обе учетные записи в этом поиске.
  2. Поскольку критерии поиска начинаются с подстановочного знака (*), он не может использовать индекс для поиска учетной записи. Это означает, что он должен просматривать каждый объект в вашем домене, чтобы найти совпадение. Это может не иметь значения, если у вас небольшой домен, но чем больше объектов у вас в домене, тем дольше это займет.

IIS дает вам точное имя пользователя, поэтому нет необходимостисделать «содержит» сравнение. Таким образом, ваш запрос может быть упрощен до:

(sAMAccountName=$current_user)

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

Вы часто будете видеть добавленные критерии ограниченияпоиск по учетным записям пользователей, например так (обратите внимание на &):

(&(objectClass=user)(objectCategory=person)(sAMAccountName=$current_user))

Но на самом деле, только пользователи могут проходить аутентификацию в IIS, и sAMAccountName уникален для всех типов объектов, поэтому он неt действительно имеет значение.

...