LDAP 新手。我计划使用 UnboundID Java API 通过非常慢的链接检查 LDAP 服务器中是否存在约 5K 条目。一是,我可以使用正确的 LDAP 搜索选项。或者通过绑定条目的 DN 来确定条目的存在。请建议,这是快速/最好的方法。
3 回答
您绝对不应该仅仅为了确定条目是否存在而执行绑定。这有几个很好的理由:
对于您尝试以不存在的用户身份绑定的情况和您尝试使用错误密码绑定的情况,符合标准的 LDAP 服务器应返回“无效凭据”响应。因此,如果您不知道某个用户的密码(如果您甚至不知道该用户是否存在,这是一个不错的选择),那么您就不能使用绑定来区分丢失的用户和错误的用户密码。
绑定尝试可能会导致写入目标条目,这可能会显着降低性能。如果您尝试使用错误的密码进行绑定,那么服务器可能会配置为跟踪失败的身份验证尝试,并且在某些情况下甚至可能会锁定用户。即使您使用正确的密码绑定,服务器也可能被配置为更新条目(例如,记录上次登录时间)。
您可以考虑其他一些选项。他们包括:
正如 Terry 建议的那样,对每个条目(这是 LDAPConnection.getEntry 方法所做的)执行基本级别的搜索,请求的属性集为“1.1”,这意味着没有属性。如果该条目不存在,您将得到“没有这样的对象”结果(这将导致 LDAP SDK 抛出 LDAPException)。如果条目确实存在,那么您将返回一个仅包含其 DN 的搜索结果条目,然后是搜索结果完成响应。
作为使用基本级别搜索的替代方法,您可以使用 LDAP 比较操作。如果您只想知道条目是否存在,这比搜索更有效,因为每个条目只有一个响应(比较结果)而不是两个(搜索结果条目和搜索结果完成)。如果条目存在,那么您将根据条目是否与比较断言匹配得到“比较真”或“比较假”的响应。如果该条目不存在,那么您将得到一个带有“没有这样的对象”结果的 LDAPException。
如果您使用的服务器支持 entryDN 操作属性(如 RFC 5020 中所述),那么您可以执行单个搜索来检索多个条目。例如,您可以构造一个过滤器,如 "(|(entryDN=uid=user.1,dc=example,dc=com)(entryDN=uid=user.2,dc=example,dc=com)(entryDN=uid =user.3,dc=example,dc=com)(entryDN=uid=user.4,dc=example,dc=com)(entryDN=uid=user.5,dc=example,dc=com))”。此示例适用于单个搜索请求,可用于确定这五个条目中的哪一个存在。您将拥有一个请求,最多包含五个搜索结果条目响应和一个搜索结果完成响应,而不是为每个条目单独请求和响应。我绝对不建议构建一个包含 5000 个元素的 OR 过滤器,
如果您使用的目录没有比您要检查的目录多得多的条目,那么您可以简单地使用您正在寻找的 DN 创建一个集合,执行子树“(objectClass = *)”搜索,然后从服务器返回的集合中删除每个条目的 DN。搜索完成后,留在集合中的条目将是服务器中不存在的条目。当然,如果您只想检查包含大量条目的服务器中的少数条目,这将是一个非常糟糕的主意。
请注意,在您尝试根据条目是否在一组搜索结果中返回来确定条目是否存在的最后两种情况下,您还将受到访问控制限制。如果您用来绑定到服务器的帐户没有权限查看您尝试检查的所有条目,那么您可能会错误地认为某个条目不存在只是因为客户端不存在有权查看它。相反,如果您无权进行检查,前两种方法可能会返回“访问权限不足”的结果,因此这也可能会阻止您做出决定。最终,这意味着您应该使用您自己的帐户
如果 DN 已知,然后客户端正在检查是否存在而不进行身份验证,则检索1.1
OID(无属性),而不是 BIND。BIND 通常比搜索慢。例如:
try {
// Connect to the server
LDAPConnection ldapConnection = new LDAPConnection(...);
try {
for(String dn:listOfDns) {
Entry entry = ldapConnection.getEntry(dn,"1.1");
}
} catch(LDAPException ex) {
// handle an exception from the search
} finally {
ldapConnection.close();
}
} catch(LDAPException ex) {
// handle an exception from the connection attempt
}
如果没有必要,不要搜索。如果您已经知道 DN,只需绑定到它。
但是通常情况是您知道其他内容,即属性值,例如mail
or displayName
,因此您必须首先搜索以找到具有该属性的条目,然后与该条目的 DN 绑定。