使用 .NET DirectoryServices 与 Sun One LDAP 通信






4.90/5 (8投票s)
使用 .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
处理 DirectoryEntry
和 DirectorySearcher
的方法,然后是 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 日:初始发布