65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 .NET DirectoryServices 与 Sun One LDAP 通信

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.90/5 (8投票s)

2009年6月24日

CPOL

3分钟阅读

viewsIcon

59033

使用 .NET DirectoryServices 添加、更新、删除和搜索 Sun One LDAP

引言

虽然网上有很多关于 DirectoryServices 的代码片段,但要找到一个能够真正连接并与 Sun One LDAP 或其他平台(而不是 AD)一起使用的代码并不容易! 这将帮助用户使用其他的 LDAP 解决方案。 

背景 

LDAP 的概念以及让网页与它通信,甚至其他客户端工具的想法都非常简单。 不幸的是,想弄清楚如何从 Active Directory (AD) 以外的任何地方获得结果并非易事。 希望您觉得这些信息有用。

** 请注意,所有代码都基于标准安装的 Sun One,未添加任何 OU 或任何特定内容。

Using the Code

这篇文章主要是代码片段。 我将演示如何连接、添加、更新、删除和查找 LDAP 条目。 这基于 Sun One,但对于任何没有 AD 的 LDAP 来说,都可能很有用。

首先,使用 LDAP 有两种不同的方法。 有使用 System.DirectoryServices处理 DirectoryEntryDirectorySearcher的方法,然后是 System.DirectoryServices.Protocols 方法,用于更直接地发送特定请求。

* 为了进行适当的处理,您可能需要在 try catch 块中包装这些语句,以防发生错误。

让我们一起探索它们!

首先,在您的项目中,添加对 System.DirectoryServices 的引用,和/或使用 System.DirectoryServices.Protocols

将以下一个或两个内容添加到 using 子句中,以使生活更轻松

using System.DirectoryServices;
using System.DirectoryServices.Protocols;

要直接连接,需要注意几件事。 有身份验证类型。 这些可能需要根据您的连接进行更改,但如果未正确配置,您可能会遇到奇怪的错误。 此外,用户名/密码与 AD 不同。 您必须为大多数第三方 LDAP 服务器明确使用完全限定的用户名。

要使用 Protocols 简单连接,您可以使用以下代码作为示例

 //Use the servername and port that you setup LDAP Directory Service on
//9605 is the example port here
LdapDirectoryIdentifier ldapDir = new LdapDirectoryIdentifier("servername", 9605);
LdapConnection ldapConn = new LdapConnection(ldapDir);
//You may need to try different types of Authentication depending on your setup
ldapConn.AuthType = AuthType.Basic;
//Update the next line to include the Fully Qualified LDAP name 
// of the user along with that user's password
System.Net.NetworkCredential myCredentials = 
	new System.Net.NetworkCredential("uid=admin,ou=Administrators,
	ou=TopologyManagement,o=netscapeRoot", "password");
//This is the actual Connection establishment here
ldapConn.Bind(myCredentials); 

现在,如果不使用 Protocols,您必须同时连接并执行操作,因此您无法像使用 Protocols 那样控制保持连接。 对于此示例,我们将连接并从 DirectoryEntry 开始。 在此示例中,该条目是根目录。 

DirectoryEntry dirEntry = new DirectoryEntry();
dirEntry.Path = @"LDAP://servername:9605/dc=example,dc=com";
dirEntry.Username = "uid=admin,ou=Administrators,
			ou=TopologyManagement,o=netscapeRoot";
dirEntry.Password = "password";
dirEntry.AuthenticationType = AuthenticationTypes.ServerBind;
dirEntry.RefreshCache();

RefreshCache 方法(上面代码的最后一行)是实际建立连接。 它连接并加载 DirectoryEntry 的所有属性和特性。 

现在让我们添加一个新用户! 使用 protocols 方法,它看起来像这样。 现在要注意的是,LDAP 服务器对添加用户有要求,例如,必须具有正确的 objectclass,并且必须具有某些属性。 下面是 Sun One 的典型属性。 请检查您的 LDAP 服务器的条目属性要求。

AddRequest addme = new AddRequest(@"uid=nuser,ou=People,dc=example,dc=com");
addme.Attributes.Add(new DirectoryAttribute("objectclass", new object[] 
	{ "top", "person", "organizationalPerson", "inetorgPerson" }));
addme.Attributes.Add(new DirectoryAttribute("uid", "nuser"));
addme.Attributes.Add(new DirectoryAttribute("givenName", "new"));
addme.Attributes.Add(new DirectoryAttribute("sn", "user"));
addme.Attributes.Add(new DirectoryAttribute("cn", "new user"));
addme.Attributes.Add(new DirectoryAttribute("userPassword", "nuser"));
ldapConn.SendRequest(addme);

好的,那么如何在没有 Protocols 方法的情况下添加内容呢? 别担心,这是可以做到的!

DirectoryEntry newUser = dirEntry.Children.Add
	("uid=nuser,ou=People,dc=example,dc=com", "person");
newUser.Properties["objectClass"].Value = new object[] 
	{ "top", "person", "organizationalPerson", "inetorgPerson" };
newUser.Properties["uid"].Value = "nuser";
newUser.Properties["givenName"].Value = "new";
newUser.Properties["sn"].Value = "user";
newUser.Properties["cn"].Value = "new user";
newUser.Properties["userPassword"].Value = "nuser";
newUser.CommitChanges();

** 请注意,dirEntry 与上面相同,即服务器的根目录。 这会将用户添加到 LDAP 服务器目录的根目录。 CommitChanges 方法为我们完成了这项工作。

好的,现在让我们找到新用户! (这对于更新用户属性或只是检查它们是否存在很有用!) 

SearchRequest findme = new SearchRequest(); 
findme.DistinguishedName = "ou=People,dc=example,dc=com"; //Find all People in this ou
findme.Filter = "(objectClass=person)"; //The type of entry we are looking for
findme.Scope = System.DirectoryServices.Protocols.SearchScope.Subtree; //We want all 
							//entries below this ou
SearchResponse results = (SearchResponse)ldapConn.SendRequest(findme); //Run the query 
							//and get results
SearchResultEntryCollection entries =  results.Entries;
for (int i = 0; i < entries.Count; i++)//Iterate through the results
{
    SearchResultEntry entry = entries[i];
    IDictionaryEnumerator attribEnum = entry.Attributes.GetEnumerator();
    while (attribEnum.MoveNext())//Iterate through the result attributes
    {        
//Attributes have one or more values so we iterate through all the values 
//for each attribute
        DirectoryAttribute subAttrib = (DirectoryAttribute)attribEnum.Value;
        for (int ic = 0; ic < subAttrib.Count; ic++)
        {
            //Attribute Name below
            attribEnum.Key.ToString();
            //Attribute Sub Value below
            subAttrib[ic].ToString();
        }
    }    
} 

同样的事情,没有 Protocols

 DirectorySearcher search = new DirectorySearcher(dirEntry);
search.Filter = "(objectClass=person)";
search.SearchScope = System.DirectoryServices.SearchScope.Subtree;
SearchResultCollection searchResults = search.FindAll();
for (int i = 0; i < searchResults.Count; i++)
{

    System.Collections.IDictionaryEnumerator subColl = 
			searchResults[i].Properties.GetEnumerator();
    while (subColl.MoveNext())
    {
        ResultPropertyValueCollection pc = (ResultPropertyValueCollection)subColl.Value;
        System.Collections.IEnumerator subPcol = pc.GetEnumerator();
        while (subPcol.MoveNext())
        {          
           //Property Name
           subColl.Key.ToString();
           //Property Value
           subPcol.Current.ToString();
        }
    }
}

好的,现在来修改一些内容! 下面将把用户添加到组中。

ModifyRequest request = new ModifyRequest();
request.DistinguishedName = distinguishedgroupname;
DirectoryAttributeModification dirmod = new DirectoryAttributeModification();
dirmod.Operation = DirectoryAttributeOperation.Add;
dirmod.Name = "uniquemember";
dirmod.Add(distinguishedusername);
request.Modifications.Add(dirmod);
ModifyResponse response = (ModifyResponse)ldapConnection.SendRequest(request); 

下面将从组中删除用户。 请注意指定修改请求类型的 dirmod.Operation

ModifyRequest request = new ModifyRequest();
request.DistinguishedName = distinguishedgroupname;
DirectoryAttributeModification dirmod = new DirectoryAttributeModification();
dirmod.Operation = DirectoryAttributeOperation.Delete;
dirmod.Name = "uniquemember";
dirmod.Add(distinguishedusername);
request.Modifications.Add(dirmod);
ModifyResponse response = (ModifyResponse)ldapConnection.SendRequest(request);

最后是关于如何删除对象的代码!

DeleteRequest request = new DeleteRequest(distinguishedname);
DeleteResponse response = (DeleteResponse)ldapConnection.SendRequest(request); 

有了这些,您应该能够使用 LDAP 解决方案来创建自己的用户管理解决方案。 我创建了一个网站,使用此代码添加/删除用户并修改用户的组。 您还可以构建一个首次同步,将存储在数据库中的所有当前用户权限加载到 LDAP 中。 切换期间大约在 10 分钟内加载了大约 8000 个用户。

玩得开心,编码愉快!

历史

  • 2009 年 6 月 24 日:初始发布
© . All rights reserved.