【问题标题】:Is my LDAP syntax wrong in search filter我的 LDAP 语法在搜索过滤器中是否错误
【发布时间】:2023-06-05 15:56:02
【问题描述】:

这是我第一次尝试向我们的 LDAP 服务器查询 AD 信息。当我尝试查询 LDAP 服务器时,这就是我要检索的内容:

我正在尝试检索计数限制为 500 条记录的所有活动员工,这些记录的显示名称以“sav”开头,有一个电子邮件地址,并且 userAccountControl 属性为 512。我遇到的问题是我只得到总共返回 8 条记录。从字面上看,我应该至少取回 10 条记录。

我对在我的搜索中未检索到的 2 条记录进行了单独搜索,每条记录都有一个电子邮件地址和一个 userAccountControl 值为 512。所以我不确定为什么这 2 条记录丢失了。

我确定我的语法有问题,但我找不到它是什么。任何帮助/方向将不胜感激。谢谢。

谷歌搜索后,我将搜索过滤器定义为:

String searchFilter = "(&(objectClass=user)(displayname="+displayname+"*"+")(mail=*)(userAccountControl=512))";

请看下面我的完整方法:

public List<String> getAutocompleteEmpRecordsList(String displayname, LdapContext ctx) {
    List<String> activeEmpAttributes = new ArrayList<String>();
    Attributes attrs = null;
    int count = 0;
    int empEmailAddrLen = 0;
    try {
        SearchControls constraints = new SearchControls();
        constraints.setCountLimit(500);          
        constraints.setSearchScope(SearchControls.SUBTREE_SCOPE);
        String[] attrIDs = {"displayname", "mail", "userAccountControl"};
        constraints.setReturningAttributes(attrIDs);
        String searchFilter = "(&(objectClass=user)(displayname="+displayname+"*"+")(mail=*)(userAccountControl=512))";
        NamingEnumeration answer = ctx.search("OU=Standard,OU=Users,DC=xxx,DC=org", searchFilter, constraints);
        if (answer != null) {
            while (answer.hasMore()) {
                attrs = ((SearchResult) answer.next()).getAttributes();
                if (attrs.get("displayname") != null) {
                    int empNameLen = attrs.get("displayname").toString().length();
                    activeEmpAttributes.add(attrs.get("displayname").toString().substring(13, empNameLen));
                }
                count++;
                ctx.close();
            }
        }
        else {
            throw new Exception("Invalid User");
        }
        System.out.println("activeEmpAttributes: " + activeEmpAttributes);
        System.out.println("count: " + activeEmpAttributes.size());
    } catch (Exception ex) {
        ex.printStackTrace();
    }
    return activeEmpAttributes;
}

【问题讨论】:

  • 语法看起来不错,但您应该查看使用单独 searchArgs 的 search() 重载,因此您的过滤器可以是 (&(objectClass=user)(displayname={0}*)(mail=*)(userAccountControl=512)),其中 {0} 指的是第一个 searchArg。

标签: active-directory ldap ldap-query


【解决方案1】:

您可能会混淆displayname 属性和cn 属性。

在 Windows 服务器上,您有一个名为 LDIDIFDE.EXE 的命令行工具,可以让您测试您的过滤器。

ldifde -f datas.ldf -d "OU=Standard,OU=THR Users,DC=txhealth,DC=org" -r "(&(objectClass=user)(displayname=sav*)(mail=*)(userAccountControl=512))"
ldifde -f datas.ldf -d "OU=Standard,OU=THR Users,DC=txhealth,DC=org" -r "(&(objectClass=user)(cn=sav*)(mail=*)(userAccountControl=512))"

在用户和计算机 MMC 中,您还可以测试您的过滤器。

启动用户和计算机活动目录:

注册请求的右键:

选择个性化搜索,您有一个常用属性的帮助选项卡:

您可以为技术属性选择个性化标签

您可以测试并复制生成的 LDAP 过滤器(您不需要双 (& 一个就足够了):

【讨论】:

  • 感谢您的回复。但是我发现了我的问题并将其发布在上面,以供可能遇到相同问题的其他人使用。
【解决方案2】:

您能否发布两个排除用户的 userAccountControl、displayName 和 mail 值?

FWIW 如果您向其添加元组索引,则 displayName 上的内侧搜索会运行得更快。

【讨论】:

  • 感谢您的回复。但是我发现了我的问题并将其发布在上面以供可能遇到相同问题的其他人使用。
【解决方案3】:

我下载了一个免费的 AD 工具来查看我需要的所有 AD,它告诉我数据不是问题,但我只是没有找到我需要的所有 OU,因为不仅仅是 1 个 OU,我们的所有用户被存储。

因此,在谷歌搜索更多之后,我在 Oracle 网站上找到了一个关于 LDAP 的页面,我将 LDAPContext 更改为 DirContext 以便我的连接在目录中进行搜索以及使用此上下文的 REFERRAL 并将值设置为“follow”避免 PartialSearchException。

我想我会发布我的发现,以防其他新手遇到同样的问题。

如果您发现我所做的更改有不利之处,请告诉我。问候。

这是我更正后的代码:

public List<String> getAutocompleteEmpRecordsList(String displayname, DirContext ctx) {
    List<String> activeEmpAttributes = new ArrayList<String>();
    Attributes attrs = null;
    int count = 0;
    int empEmailAddrLen = 0;
    try {
        SearchControls constraints = new SearchControls();
        constraints.setCountLimit(500); 
        constraints.setSearchScope(SearchControls.SUBTREE_SCOPE);
        String[] attrIDs = {"displayname", "mail", "userAccountControl"};
        constraints.setReturningAttributes(attrIDs);
        String searchFilter = "(&(objectClass=user)(displayname="+displayname.trim()+"*"+")(mail=*)(userAccountControl=512))";
        NamingEnumeration answer = ctx.search("DC=xxx,DC=org", searchFilter, constraints);
        if (answer != null) {
            while (answer.hasMore()) {
                attrs = ((SearchResult) answer.next()).getAttributes();
                if (attrs.get("displayname") != null) {
                    int empNameLen = attrs.get("displayname").toString().length();
                    activeEmpAttributes.add(attrs.get("displayname").toString().substring(13, empNameLen));
                }
                count++;
                ctx.close();
            }
        }
        else {
            throw new Exception("Invalid User");
        }
        System.out.println("activeEmpAttributes: " + activeEmpAttributes);
        System.out.println("count: " + activeEmpAttributes.size());
    } catch (Exception ex) {
        ex.printStackTrace();
    }
    return activeEmpAttributes;
}

还是谢谢。

【讨论】:

    最近更新 更多