一天中的好时光, 我遇到了为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
我想提供以下功能:
Name FamilyName
,这将导致Name FamilyName
和FamilyName Name
'Имя Фамилия
,搜索应从(&(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;
}
}
}
}
答案 0 :(得分:1)
您的查询确实无效。
在LDAP查询语法中,“ this or that”条件写为(|(this)(that))
。但是,您已将|
{em>插入之间。它必须在最前面。它应该看起来像这样:
(|(&(sn=' . $firstName . ')(givenname=' . $lastName . '))(cn=' . $combination . '*))