简体   繁体   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?

I'm creating an intranet PHP website without any login requirements.我正在创建一个没有任何登录要求的 Intranet PHP 网站。 I have an IIS application (based on PHP), authentication is done with Windows Authentication (Anonymous Authentication is disabled).我有一个 IIS 应用程序(基于 PHP),使用 Windows 身份验证完成身份验证(禁用匿名身份验证)。 I've successfully managed to set up IIS and windows authentication with some GPO tweaks.我通过一些 GPO 调整成功地设置了 IIS 和 windows 身份验证。 My simple PHP page contains $_SERVER['REMOTE_USER'];我的简单 PHP 页面包含$_SERVER['REMOTE_USER']; so active directory user without any login prompts can see DOMAIN\User.Name因此没有任何登录提示的活动目录用户可以看到 DOMAIN\User.Name

In my understanding IIS Windows authentication is very limited and can only display the user's name and domain name.在我的理解中IIS Windows 认证非常有限,只能显示用户名和域名。 So I enabled LDAP to display more information about the user such as display name or phone number.所以我启用了 LDAP 来显示有关用户的更多信息,例如显示名称或电话号码。 But I'm stuck here because as far as I know, LDAP uses username and password bind to retrieve information.但我被困在这里,因为据我所知,LDAP 使用用户名和密码绑定来检索信息。 When I use active directory admin credentials it gives me a table of all user's information but how to filter that table to display only current user information (based on windows authentication).当我使用活动目录管理员凭据时,它为我提供了一个包含所有用户信息的表,但如何过滤该表以仅显示当前用户信息(基于 windows 身份验证)。

Code:代码:

<?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 : Managed to filter current user by editing LDAP filter:编辑:通过编辑 LDAP 过滤器来过滤当前用户:

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

Your query is almost right, but it's working in a roundabout way:)您的查询几乎是正确的,但它以迂回的方式工作:)

There is no objectCategory called persons .没有objectCategory称为persons It's just person (no "s").这只是person (没有“s”)。 So objectCategory=persons is always false for every object on your domain.因此,对于您域中的每个 object, objectCategory=persons始终为 false。 But it's working because you're using an OR ( | ).但它正在工作,因为您使用的是 OR ( | )。

So the only criteria it's really using is sAMAccountName=*$current_user* .所以它真正使用的唯一标准是sAMAccountName=*$current_user* But that's asking for any object where sAMAccountName contains $current_user .但这要求sAMAccountName包含$current_user的任何 object 。 That has two unintended consequences:这有两个意想不到的后果:

  1. If you have a user called neil , and another called oneil , then whenever neil logs in, you will find both accounts in that search.如果您有一个名为neil的用户和另一个名为oneil的用户,那么每当neil登录时,您都会在该搜索中找到这两个帐户。
  2. Because your search criteria starts with a wildcard ( * ), it cannot use the index to find the account.因为您的搜索条件以通配符 ( * ) 开头,所以它不能使用索引来查找帐户。 That means that it has to look through every object on your domain to find a match.这意味着它必须查看您域中的每个 object 才能找到匹配项。 That might not matter if you have a small domain, but the more objects you have on your domain, the longer it will take.如果您的域很小,这可能无关紧要,但是域中的对象越多,所需的时间就越长。

IIS is giving you the exact username, so there is no need to make a "contains" comparison. IIS 为您提供准确的用户名,因此无需进行“包含”比较。 So your query can be simplified to:因此,您的查询可以简化为:

(sAMAccountName=$current_user)

Since sAMAccountName is an indexed attribute, that will be a super fast query.由于sAMAccountName是一个索引属性,这将是一个超级快速的查询。

You will often see the added criteria of limiting the search to user accounts, like this (notice the & ):您经常会看到将搜索限制为用户帐户的附加条件,如下所示(注意& ):

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

But really, only users can authenticate to IIS, and the sAMAccountName is unique across all object types, so it doesn't really matter.但实际上,只有用户可以对 IIS 进行身份验证,并且sAMAccountName在所有 object 类型中都是唯一的,所以这并不重要。

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

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