在AD LDAP中查找用户

时间:2019-03-07 09:48:27

标签: php active-directory ldap

一天中的好时光, 我遇到了为LDAP构建过滤器的问题。

在实际问题之前的注释很少:

Фамилия = Family Name (will be presented as FamilyName)  
Имя = Name (will be presented as Name)  
Отчество = Patronymic (will be presented as Patronymic)

我有一个用户在广告中包含以下信息:

CN=Фамилия Имя Отчество
sn=FamilyName
givenname=Name

我想提供以下功能:

  1. 用户可以在网站上的字段中输入Name FamilyName,这将导致Name FamilyNameFamilyName Name'
  2. 包含2个过滤器的数组
  3. 用户可以输入Имя Фамилия,搜索应从(&(sn =)(givenname =))切换为(cn =)

目前,我有以下代码来完成第一个选择:

    /**
     * Generate search terms
     * @param string $query
     * @return LDAPSearcher
     */
    protected function generateSearchTerms(string $query) : self {
        $this->searchTerms = [];
        $explode = explode(' ', $query);
        $combinations = [];
        array_combinations($explode, $combinations);

        foreach($combinations as $index => $combination) {
            if (false !== strpos($combination, ' ')) {
                [$firstName, $lastName] = explode(' ', $combination);
                $this->searchTerms[] = [
                    'sn'        =>  $lastName,
                    'cn'        =>  $combination,
                    'givenname' =>  $firstName,
                    'filter'    =>  '(&(sn=' . $firstName . ')(givenname=' . $lastName . '))'
                ];
            }
        }

        return $this;
    }

当用户使用其名字的姓氏和名字的拉丁字母表示时,效果很好,但是当我想切换到使用CN时,我不知道该怎么做。
我为过滤器尝试了以下代码,但是它表明过滤器不正确:
((&(sn=' . $firstName . ')(givenname=' . $lastName . '))|(cn=' . $combination . '*))

我们非常感谢您的帮助!

PS 无关紧要是将哪个变量分配给SN或GivenName,因为组合仍然会匹配正确的用户,因此我为每个用户最多运行3次搜索以确保正确找到一个(只是为了消除为变量分配正确值的可能性)

P.P.S。使用以下代码段生成组合

if (! function_exists('array_combinations')) {

    function array_combinations(array $source, array &$target, ?string $tempString = null) {
        if ($tempString !== null) {
            $target[] = $tempString;
        }
        $size = \count($source);
        for ($i = 0; $i < $size; $i++) {
            $copy = $source;
            $element = array_splice($copy, $i, 1);
            $tmp = null;
            if ($tempString !== null) {
                $tmp = $tempString . ' ' . $element[0];
            } else {
                $tmp = $element[0];
            }
            if (\count($copy) > 0) {
                array_combinations($copy, $target, $tmp);
            } else {
                $target[] = $tmp;
            }
        }

    }

}

1 个答案:

答案 0 :(得分:1)

您的查询确实无效。

在LDAP查询语法中,“ this or that”条件写为(|(this)(that))。但是,您已将| {em>插入之间。它必须在最前面。它应该看起来像这样:

(|(&(sn=' . $firstName . ')(givenname=' . $lastName . '))(cn=' . $combination . '*))