使用LDAP和PHP

时间:2016-02-04 04:40:35

标签: php ldap

我有一个LDAP身份验证系统,可以从AD查找和检索memberOf属性,但我不知道如何获取嵌套组成员资格。我知道memberOf:1.2.840.113556.1.4.1941:扩展但不确定如何使其适应我的代码。我正在运行的代码如下(它不是嵌套组)。有经验的人可以帮忙吗?

IN CONFIG.PHP

$adbase = "some.domain.com";
$adtree = "OU=All Departments,DC=some,DC=domain,DC=com";
$group_admins = "Test App Admins";
$group_staff = "Test App Staff";

IN RUN.PHP

function extract_unit($string, $start, $end) {
    $pos = stripos($string, $start);
    $str = substr($string, $pos);
    $str_two = substr($str, strlen($start));
    $second_pos = stripos($str_two, $end);
    $str_three = substr($str_two, 0, $second_pos);
    $unit = trim($str_three); // remove whitespaces
    return $unit;
    }

extract($_POST);

if($action == "logon") {
    $ldap = ldap_connect($adbase);
    $userID = "$user@$adbase";
    $bind = @ldap_bind($ldap, $userID, $pass);

    if($bind == true) {
        // assign session variables
        $_SESSION['username'] = $user;

        // get group memberships
        $results = ldap_search($ldap, $adtree, "(samaccountname=$user)",array("memberof", "mail"));
        $entries = ldap_get_entries($ldap, $results);

        // get group count (first entry) and group listings
        $beat = 0; $str = ""; foreach($entries[0]['memberof'] as $temp) {
            if($beat == 0) {
                $count = $temp;
                }
            else {
                $temp = extract_unit($temp, "CN=", ",OU=");
                $str .= "$temp, ";
                $groups[] = $temp;
                }
            $beat++;
            }
        // return the mail address, stackoverflow.com/questions/16224720/searching-for-email-address-ldap-active-directory
        $mail = $entries[0]["mail"][0];
        // assign session variables
        $_SESSION['mail'] = $mail;

        // groups defined in config.php
        $client = "You are logged in as a client.";
        if(in_array($group_admins, $groups)) {
            $_SESSION['admin'] = true;
            $client = "You are logged in as an administrator.";
            }
        else {
            $_SESSION['admin'] = false;
            }
        // groups defined in config.php
        if(in_array($group_staff, $groups)) {
            $_SESSION['staff'] = true;
            $client = "You are logged in as staff.";
            }
        else {
            $_SESSION['staff'] = false;
            }

        // if it returns true user was found
        print "<h2>Signed in as $user</h2>\n";
        print "$client<br>\n";
        print "<img src=\"./images/next.png\"> <a href=\"./?d=welcome\">Continue ...</a>\n";
        print "<!-- count is $count -->";
        print "<!-- groups are $str -->";
        print "<!-- mail is $mail -->";
        }
    else {
        print "<h2>Login attempt failed</h2>\n";
        print "<img src=\"./images/logon.png\"> <a href=\"./?d=user/logon\">You may try again ...</a>\n";
        }
    }

2 个答案:

答案 0 :(得分:1)

我最终开始工作,但我不得不走另一条道路。

这是我最终使用嵌套组进行PHP LDAP身份验证的代码。 这假设正在检查用户名以查看它是否存在于组或嵌套组中。如果你拿出(samaccountname = $ user),那么它将返回该组中所有用户的列表,但这将花费相当长的时间(不到一秒钟就可以达到30秒以上)。

/*
$adBase like "some.domain.com"
$ldBase like "OU=Users,DC=some,DC=domain,DC=com"
$admins like "CN=Test Admins,OU=Groups"
$staff like "CN=Test Staff,OU=Groups"
$ldaplink like "ldap://ldap.domain.com/o=domain.com??sub?"
*/

$ldap   = ldap_connect($adBase);
$bind   = @ldap_bind($ldap, "$user@$adBase", $pass);

$admins = $ldAdmin.",".$ldBase;
$staffs = $ldStaff.",".$ldBase;
$filtrA = "(&(objectClass=user)(samaccountname=$user)(memberof:1.2.840.113556.1.4.1941:=$admins))";
$filtrS = "(&(objectClass=user)(samaccountname=$user)(memberof:1.2.840.113556.1.4.1941:=$staffs))";

if($bind) {
    // default message if not found in either group
    $client = "You are logged in as a client.";

    // get basic info first; stackoverflow.com/questions/1622472...
    $result = ldap_search($ldap, $ldBase, "(samaccountname=$user)", array("mail"));
    $entries = ldap_get_entries($ldap, $result);
    $mail = $entries[0]["mail"][0];
        $_SESSION['username'] = $user;
        $_SESSION['mail'] = $mail;


    #region check admin/nested group
    $link1A = ldap_search($ldap, $ldBase, $filtrA, array("name"));
    $link2A = ldap_get_entries($ldap, $link1A);
    @$nameA = $link2A[0]["name"][0]; // throws error if not defined but that's what we're testing thus the @

    if($nameA == true) {
        // user was found in administrators or in nested group
        $_SESSION['admin'] = true;
        $client = "You are logged in as an administrator.";
        }
    else {
        $_SESSION['admin'] = false;
        }
    #endregion

    #region check staff/nested group
    $link1S = ldap_search($ldap, $ldBase, $filtrS, array("name"));
    $link2S = ldap_get_entries($ldap, $link1S);
    @$nameS = $link2S[0]["name"][0]; // throws error if not defined but that's what we're testing thus the @

    if($nameS == true) {
        // user was found in staff or in nested group
        $_SESSION['staff'] = true;
        $client = "You are logged in as staff.";
        }
    else {
        $_SESSION['staff'] = false;
        }
    #endregion

    // if it returns true user was found
    print "<h2>Signed in as $user</h2>\n";
    print "$client<br>\n";
    print "<img src=\"./images/next.png\"> <a href=\"./?d=tem/welcome\">Continue ...</a>\n";
    print "<!-- mail is $mail -->";
    }
else {
    print "<h2>Login attempt failed</h2>\n";
    print "<img src=\"./images/logon.png\"> <a href=\"./?d=user/logon\">You may try again ...</a>\n";
    }

答案 1 :(得分:0)

您需要使用类似于:

的EXTENSIBLE MATCH过滤器语法构造查询

(memberOf:1.2.840.113556.1.4.1941:= CN = GroupOne,OU =安全组,OU =组,DC = YOURDOMAIN,DC = NET)

哪个RESOLVES ALL MEMBERS (INCLUDING NESTED) SECURITY GROUPS (REQUIRES AT LEAST WINDOWS 2003 SP2)