如何通过PHP获取Active Directory跨域组group1的所有用户列表?
多域Active Directory环境下获取跨域组成员的解决方案
你的问题出在两个核心点:
- 代码里关闭了LDAP引用跳转(
LDAP_OPT_REFERRALS设为0),AD查询跨域对象时会返回指向子域的引用,关闭后客户端不会自动去子域查询对应数据 - 用
memberOf反向查询的方式,在多域环境下无法覆盖子域用户——子域用户的对象存储在子域目录树中,主域的LDAP搜索无法直接捕获其memberOf关联
下面是两种可行的解决方法,优先推荐第一种:
方法一:直接查询组的member属性(最可靠)
组对象的member属性会完整记录所有成员的DN(包括子域用户),我们可以先获取组的所有成员DN,再逐个查询用户信息,同时开启LDAP引用跳转让客户端自动处理子域查询。
修改后的代码如下:
header('Content-Type: application/json; charset=utf-8'); set_time_limit(30); error_reporting(E_ALL); ini_set('error_reporting', E_ALL); ini_set('display_errors',1); $ldaphost = "ldap://domain.local"; $ldapport = "389"; $ldap = ldap_connect($ldaphost,$ldapport) or die('Cannot connect to LDAP Server.'); // 启用LDAPv3协议 ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3) or die('Unable to set LDAP protocol version'); // 开启引用跳转,允许跨域查询 ldap_set_option($ldap, LDAP_OPT_REFERRALS, 1) or die('Unable to set LDAP OPT REFERRALS'); if ($ldap) { $ldapuser = 'ldap_system'; $ldappass = '123456'; $bind = ldap_bind($ldap,$ldapuser,$ldappass); if ($bind) { // 先查询group1组对象,获取所有成员的DN列表 $groupDN = "CN=group1,OU=PQ185,OU=testGroups,DC=domain,DC=local"; $groupQuery = ldap_read($ldap, $groupDN, "(objectClass=group)", array('member')); $groupData = ldap_get_entries($ldap, $groupQuery); $userdata = array(); if ($groupData['count'] > 0 && isset($groupData[0]['member'])) { // 遍历每个成员DN,查询对应的用户信息 for ($i=0; $i < $groupData[0]['member']['count']; $i++) { $memberDN = $groupData[0]['member'][$i]; // 查询用户信息,过滤已禁用的账户 $userQuery = ldap_read($ldap, $memberDN, "(!(userAccountControl:1.2.840.113556.1.4.803:=2))", array('displayname', 'samaccountname', 'description')); $userData = ldap_get_entries($ldap, $userQuery); if ($userData['count'] > 0) { array_push( $userdata, array( 'displayname' => $userData[0]['displayname'][0] ?? '', 'samaccountname' => $userData[0]['samaccountname'][0] ?? '', 'description' => $userData[0]['description'][0] ?? '' ) ); } } } $json = json_encode($userdata); echo $json; } }
方法二:开启引用后使用memberOf查询(需注意权限)
如果坚持用memberOf反向查询,需要开启LDAP引用,并确保搜索范围覆盖整个林,同时绑定账户要有跨域查询权限。
修改点:
- 将
LDAP_OPT_REFERRALS设为1 - 保持搜索基DN为
DC=domain,DC=local(如果主域是林根节点),或改用全局编录端口3268连接(ldap://domain.local:3268) - 搜索过滤器保持不变
这种方式可靠性不如方法一,因为部分子域可能无法返回memberOf的反向引用,仅作为备选方案。
补充注意事项
- 确保绑定账户
ldap_system拥有查询所有子域用户的权限,否则会无法获取子域数据 - 若遇到超时问题,可适当延长
set_time_limit的数值 - 处理用户属性时添加
?? '',避免出现未定义索引错误
内容的提问来源于stack exchange,提问作者Abbosbek Alimov
相关产品推荐
相关产品推荐

