繁体   English   中英

如何根据 IIS windows 身份验证过滤 ldap 活动目录用户信息,并在 ZE1BFD762321E409C42C 网站中显示该信息?

[英]how to filter ldap active directory users information based on IIS windows authentication and display that information in php website?

我正在创建一个没有任何登录要求的 Intranet PHP 网站。 我有一个 IIS 应用程序(基于 PHP),使用 Windows 身份验证完成身份验证(禁用匿名身份验证)。 我通过一些 GPO 调整成功地设置了 IIS 和 windows 身份验证。 我的简单 PHP 页面包含$_SERVER['REMOTE_USER']; 因此没有任何登录提示的活动目录用户可以看到 DOMAIN\User.Name

在我的理解中IIS Windows 认证非常有限,只能显示用户名和域名。 所以我启用了 LDAP 来显示有关用户的更多信息,例如显示名称或电话号码。 但我被困在这里,因为据我所知,LDAP 使用用户名和密码绑定来检索信息。 当我使用活动目录管理员凭据时,它为我提供了一个包含所有用户信息的表,但如何过滤该表以仅显示当前用户信息(基于 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>");
}
?>

编辑:通过编辑 LDAP 过滤器来过滤当前用户:

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

您的查询几乎是正确的,但它以迂回的方式工作:)

没有objectCategory称为persons 这只是person (没有“s”)。 因此,对于您域中的每个 object, objectCategory=persons始终为 false。 但它正在工作,因为您使用的是 OR ( | )。

所以它真正使用的唯一标准是sAMAccountName=*$current_user* 但这要求sAMAccountName包含$current_user的任何 object 。 这有两个意想不到的后果:

  1. 如果您有一个名为neil的用户和另一个名为oneil的用户,那么每当neil登录时,您都会在该搜索中找到这两个帐户。
  2. 因为您的搜索条件以通配符 ( * ) 开头,所以它不能使用索引来查找帐户。 这意味着它必须查看您域中的每个 object 才能找到匹配项。 如果您的域很小,这可能无关紧要,但是域中的对象越多,所需的时间就越长。

IIS 为您提供准确的用户名,因此无需进行“包含”比较。 因此,您的查询可以简化为:

(sAMAccountName=$current_user)

由于sAMAccountName是一个索引属性,这将是一个超级快速的查询。

您经常会看到将搜索限制为用户帐户的附加条件,如下所示(注意& ):

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

但实际上,只有用户可以对 IIS 进行身份验证,并且sAMAccountName在所有 object 类型中都是唯一的,所以这并不重要。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM