PHP中的Active Directory验证速度很慢

时间:2015-11-24 16:51:01

标签: php performance active-directory ldap

所以我正在验证活动目录中的用户名,密码和组成员身份,如下所示:

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个组。

1 个答案:

答案 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中修复了