所以我正在验证活动目录中的用户名,密码和组成员身份,如下所示:
function validate($username, $password, $groupname = null) {
if ($username && $password) {
$link = ldap_connect($domain);
if ($link) {
ldap_set_option($link, LDAP_OPT_PROTOCOL_VERSION, 3);
$bind = ldap_bind($link, $username, $password);
if ($bind) {
if ($groupname) {
$filter = "(samAccountName=".$username.")";
$attrs = array("memberOf");
$res = ldap_search($link, $baseDN, $filter, $attrs);
$entries = ldap_get_entries($link, $res);
$isMember = false;
if ($entries && $entries[0] && $entries[0]['memberof']) {
$arr = $entries[0]['memberof'];
foreach ($arr as $key => $value) {
if ($key != 'count') {
$isMember = $isMember || preg_match("|".preg_quote($groupname)."|", $value);
}
}
}
return $isMember;
} else {
return true;
}
} else {
return false;
}
} else {
error_log("Could not connect to Active Directory");
return false;
}
} else {
error_log("Username or password missing");
return false;
}
}
这是正常的,但痛苦慢,需要2~3分钟才能验证用户是否是某个组的成员..如果我省略了组成员资格检查它几乎运行瞬间。如何加快速度(没有缓存)?
因为从问题中不清楚,瓶颈是ldap_search
函数需要~127秒,程序的其余部分在不到一秒的时间内运行。还应该补充一点,我们只有大约20个AD用户和10个组。
答案 0 :(得分:1)
首先,它看起来像foreach
- 循环,preg_match
内部需要一些时间。特别是如果有很多团体需要检查。
然而很明显AD中只有10个组和大约20个用户,所以它必须是不同的。
最后,这是一个缺少超时的问题。在ldap_set_option($connection, LDAP_OPT_NETWORK_TIMEOUT, 10);
解决问题之前添加ldap_search()
。
在这种特殊情况下,看起来好像已经打开了与LDAP服务器的连接但LDAP服务器没有正确响应,因此客户端正在等待响应,直到达到超时。将此超时设置为比默认值(这是不确定的)小得多的值导致ldap_search更早地返回,因为它不再需要等待。
AFAIK已经在PHP-5.6.14和PHP-7.0.0中修复了