仅凭登录凭据,通过LDAP和PHP获取用户可读名称

3
我正在将我的登录表单与微软Active Directory集成。我使用LDAP php库验证用户。
当用户尝试登录时,他们输入用户名和密码。连接到服务器成功,通过“LDAP_bind”认证也会根据值的正确性给出真或假。现在我无法检索用户的真实姓名以在屏幕上显示它。
我拥有的所有信息都是带有端口号的ldap uri,以及通过web表单输入的用户名和密码。
这是我目前的代码:
$ldap = ldap_connect("ldap://abc.xyz:123");
if ($bind = ldap_bind($ldap, $_REQUEST['username'].'@abc.xyz',$_REQUEST['password'])) 
{ echo "Welcome". $_REQUEST['username'];}

$_REQUEST['username']不易读,所以我需要阅读此用户属性或仅显示名称。

ldap_search和ldap_read函数没有帮助,我尝试了这段代码:

$ldap_base_dn = 'DC=abc,DC=xyz';
$search_filter = "(objectclass=*)";
$result = ldap_search($ldap_connection, $ldap_base_dn, $search_filter);

没有运气,除了用户名和密码以及LDAP URI之外,我还需要哪些其他信息才能成功地执行ldap_search或ldap_read。换句话说,这是否只需要有用户名、密码和LDAP URI就可以完成?

3个回答

2
您应该能够像这样进行搜索:
$upn = $_REQUEST['username'].'@abc.xyz';
$attributes = ['displayname'];
$filter = "(&(objectClass=user)(objectCategory=person)(userPrincipalName=".ldap_escape($upn, null, LDAP_ESCAPE_FILTER)."))";
$baseDn = "DC=abc,DC=xyz";
$results = ldap_search($ldap, $baseDn, $filter, $attributes);
$info = ldap_get_entries($ldap, $results);

// This is what you're looking for...
var_dump($info[0]['displayname'][0]);

此外,请确保使用以下选项进行绑定:

$ldap = ldap_connect("ldap://abc.xyz:123");
ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
if ($bind = ldap_bind($ldap, $_REQUEST['username'].'@abc.xyz',$_REQUEST['password']))

非常感谢!它在我这里起作用了。我的问题终于解决了。非常感谢。请注意,我将筛选行更改为:$filter = "(&(objectClass=user)(objectCategory=person)(userPrincipalName=".$upn."))"; 没有转义函数。 - user-stacker

0

在返回DisplayName值时,我建议您使用搜索过滤器查找samaccountname(用户名),可以使用简单的内容如(samaccountname=$u),其中$u是来自LDAP连接的用户名。如果您的Active Directory/Open Directory有很多对象,我肯定建议将其定位到OU,因为此查询可能会很快失败。

我对您的代码进行了进一步更改,使其现在运行在一个函数内,该函数需要3个参数并在连接或身份验证失败时返回false。

检查LDAP - 如果成功登录,则返回DisplayName,如果登录或连接失败,则返回FALSE(BOOL)

function chkLDAP($u, $pass, $domain) {

    $dom = "$domain\\"; //Domain Prefix for UNAME which ouputs "domain\"
    $user = $dom . $u; 
    $hostname = 'ldap://abc.com';
    $baseDN = 'OU=users, DC=abc, DC=com'; //Narrow down if you have alot of objects as search could take along time
    $search = "(samaccountname=$u)"; //Compare with Username

    $ldap = ldap_connect($hostname);

    if ($ldap) {

        $ldapbind = ldap_bind($ldap, $user, $pass);

        if ($ldapbind) {

            $ldapSearch = ldap_search($ldap, $baseDN, $search);
            $entry = ldap_first_entry($ldap, $ldapSearch);
            $info = ldap_get_values($ldap, $entry, "displayname"); 

            return $info[0];

        }

        return false; //Failed Auth

    } 

      return false; //Connection Failed

}

只需测试 false 函数,确保在使用之前有一个 displayname

运行函数:

$displayName = chkLDAP($_REQUEST['username'], $_REQUEST['password'], 'abc.com'); //Run Function - Returns False if Failed or Displayname if True

if ($displayName !== false) {

    echo $displayName;

} else {

    echo "Username or Password Incorrect!";

}

请参见:

http://php.net/manual/en/function.ldap-get-values.php


谢谢,但是它对我没有起作用,它给了我一个警告。 - user-stacker

0

对于需要验证特定组织单位中是否存在用户的人,这对我很有效。 (借助@kitson88回应的帮助)

    function validateLogin($username,$password)
{
            
    $ldap_dn = "$username@alhait.com";
    $ldap_password =$password;
    
    $ldap_con = ldap_connect("server");
    ldap_set_option($ldap_con, LDAP_OPT_PROTOCOL_VERSION, 3);

    if(@ldap_bind($ldap_con,$ldap_dn,$ldap_password))
    {
         $baseDN = 'OU=trainers,DC=alhait,DC=com';
          $search = "(samaccountname=$username)";
        $ldapSearch = ldap_search($ldap_con, $baseDN, $search);
        $entry = ldap_first_entry($ldap_con, $ldapSearch);
        $info = ldap_get_values($ldap_con, $entry, "displayname"); 
        // var_dump($info[0]);
        if($info[0]!=null)
        {
            return true;
        }
    }else{
        return false;
    }
        //echo "Invalid Credential";
        return false;
    
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接