从.NET连接到LDAP服务器

问题描述:

我建议使用System.DirectoryServices.Protocols以支持连接到Active Directoy here以外的LDAP服务器。
不幸的是,它我没有能够正确地搜索目录。我希望能够获得用户的某个属性(例如mail)。这很容易通过使用DirectorySearcher类在System.DirectoryServices名称空间中完成。我如何在System.DirectoryServices.Protocols命名空间中实现相同的功能。这是我到目前为止有:从.NET连接到LDAP服务器

var domainParts = domain.Split('.'); 
string targetOu = string.Format("cn=builtin,dc={0},dc={1}", domainParts[0], domainParts[1]); 
string ldapSearchFilter = string.Format("(&(ObjectClass={0})(sAMAccountName={1}))", "person", username); 

// establish a connection to the directory 
LdapConnection connection = new LdapConnection(
           new LdapDirectoryIdentifier(domain), 
           new NetworkCredential() { UserName = username, 
                Password = "MyPassword" }); 
SearchRequest searchRequest = new SearchRequest(
       targetOu, ldapSearchFilter, SearchScope.OneLevel, new[] {"mail"}); 

此代码引发DirectoryOperationException类型的异常与消息The object does not exist

我怀疑我的targetOuldapSearchFilter变量有问题。

谢谢。

+0

这是违反非Microsoft LDAP? – 2012-01-02 11:16:34

+0

它应该同时支持(例如OpenLDAP)。 – Kamyar 2012-01-02 11:18:11

我怀疑主要问题可能是:samAccountName是严格限制Windows的属性,其他LDAP服务器不知道。因此,如果您要违反非Active Directory LDAP,则应该使用其他方法进行搜索 - 例如, sn(用于姓氏或姓氏),givenName(名字),可能是displayName

另一个有趣的选择可能是使用ANR(模棱两可的名称解析)搜索 - 请参阅大致位于中间的这个page on SelfADSI,其中解释ANR。

有了ANR,你会写你的查询是这样的:

string ldapSearchFilter = 
    string.Format("(&(ObjectCategory={0})(anr={1}))", "person", username); 

我也改变ObjectClassObjectCategory的原因有两个:

  • ObjectCategory是单值,例如只包含一个值(ObjectClass是多值)
  • ObjectCategory通常索引,因此搜索通常使用速度快了很多ObjectCategory

这是否返回你正在寻找的结果?

+0

感谢您的快速回复。我改变了过滤器以使用'anr'和'ObjectCategory'。例外消失了。但'searchResponse.Entries'有0个元素。我现在正在查询AD服务。如果我使用'System.DirectoryServices',我可以正确地获得邮件属性。 – Kamyar 2012-01-02 11:34:29

+0

@Kamyar:你可以在S.DS中针对OpenLDAP运行查询吗? – 2012-01-02 11:37:08

+0

不,不幸的是我无法访问OpenLDAP服务器。但是使用'System.DirectoryServices.Protocols'并在AD中产生结果是一个很好的步骤。我可以稍后测试OpenLDAP。 – Kamyar 2012-01-02 11:40:27