PHP实现Active Directory中通过objectGUID搜索用户的问题
我是一名PHP新手(英语欠佳,敬请谅解),正在开发对接LDAP目录的PHP API,需要在Active Directory(AD)中通过objectGUID搜索用户,但发现无法匹配超过2个字符的内容。
我尝试参考ldap_search()的PHP文档中的方法:
ldap_search($ds,"dc=blahblah,dc=com", "(objectGUID=\\AE\\C3\\23\\35\\F7)");
但不知道如何替换其中的AE、C3等内容,我的目标GUID为:
$id = "4a3ef66a-ff9f-4e84-ad8d-dd3378e8df19";
我先进行了简单测试:
$filters = "(objectGUID=*\\4a*)"; //(objectGUID=*\4a*)
→ 可以成功找到用户。
但尝试更多字符时均失败:
$filters = "(objectGUID=\4a3e)"; //(objectGUID=\4a3e)
→ 执行`ldap_search`后调用`ldap_get_entries`,结果`count=0` 2. ```php $filters = "(objectGUID=*\\4a\\3e*)"; //(objectGUID=*\4a\3e*)
→ 结果count=0
3. ```php
$filters = "(objectGUID=\4a-3e)"; //(objectGUID=\4a-3e)
→ 结果`count=0` 4. ```php $filters = "(objectGUID=*\\4a*3e*)"; //(objectGUID=*\4a*3e*)
→ 结果count=0
请问有没有在PHP中通过objectGUID搜索AD用户的有效方法?感谢解答。
核心原因:AD中objectGUID的存储格式
Active Directory中的objectGUID是二进制数据,不是字符串格式。你看到的4a3ef66a-ff9f-4e84-ad8d-dd3378e8df19是它的字符串展示形式,但LDAP搜索时需要将这个字符串转换为对应的二进制字节序列,再转成\XX格式的十六进制转义字符串,才能正确匹配。
你的测试中只匹配\4a成功,是因为单个转义的十六进制字符刚好对应二进制中的一个字节,但多字符的错误写法没有对应到正确的二进制序列,所以无法匹配。
正确的GUID转换方法
要把字符串格式的GUID转换成LDAP过滤器可用的格式,需要以下步骤:
- 去掉GUID中的所有
-分隔符 - 按AD的存储规则反转字节顺序
- 把每个字节转成
\XX的转义格式
PHP实现代码
function guidToLdapFilter($guid) { // 移除GUID中的横杠 $guid = str_replace('-', '', $guid); // 按AD的字节存储顺序拆分并反转对应段 $bytes = [ substr($guid, 6, 2), substr($guid, 4, 2), substr($guid, 2, 2), substr($guid, 0, 2), substr($guid, 10, 2), substr($guid, 8, 2), substr($guid, 14, 2), substr($guid, 12, 2), substr($guid, 16, 4), substr($guid, 20, 12) ]; // 拼接成LDAP过滤器需要的转义格式 $escaped = implode('\\', $bytes); return "(objectGUID=\\$escaped)"; } // 使用示例 $id = "4a3ef66a-ff9f-4e84-ad8d-dd3378e8df19"; $filter = guidToLdapFilter($id); // 执行LDAP搜索 $result = ldap_search($ds, "dc=blahblah,dc=com", $filter); $entries = ldap_get_entries($ds, $result);
之前尝试失败的原因
*\\4a3e*:4a3e被当作单个十六进制值解析,但实际是两个独立字节,LDAP无法识别无效的单字节值,导致匹配失败。*\\4a\\3e*:虽然拆分了字节,但未遵循AD的GUID字节存储顺序,转义后的序列和AD中实际存储的二进制数据不匹配。- 带
-的写法完全不符合LDAP对二进制属性的匹配规则,自然无法找到结果。
补充:模糊搜索(若需)
如果需要用objectGUID的部分内容模糊搜索,同样要确保转义的是正确的字节序列。比如要匹配开头的4a3e对应的二进制,需先转成AD存储顺序的3e4a,再写成:
$filter = "(objectGUID=*\\3e\\4a*)";
这样才能正确匹配AD中存储的二进制数据。
内容的提问来源于stack exchange,提问作者Enocki

