活动目录基础知识
在正式探讨.NET集成之前,让我们先从活动目录的一些基本术语开始。
微软将X.500目录服务模型作为活动目录的蓝图。X.500标准在逻辑上将目录服务结构分割为servername.subdomainname.domainname.com(服务器名.子域名.域名.com)布局。在X.500里,目录信息被保存在一个叫做目录系统代理(Directory System Agent)的多层次布局里。微软根据X.500定义的基本原则来设计活动目录,但是它并不与X.500的实现相兼容。
活动目录里的每个对象都有一个识别名,用来识别对象所在的域以及到达对象的路径。活动目录里的一个典型识别名是:
CN=Tony Patton,OU=Contributors,DC=TechRepublic
这个识别名由下面这几部分组成:
- CN:公共名,用来定义目录下的对象。在本文里,公共名是Tony Patton。
- OU:对象所属的组织单位。
- DC:对象的域。也就是用于活动目录的DNS名称,在我们的例子里是TechRepublic。
就如分解开的识别名所表示的,活动目录系统是一个多层树。这个树上的每个节点代表网络上的一个可用资源或者服务。在先前的例子里,最顶上的节点是TechRepublic;它含有Contributors OU,后者包括一个或者多个对象(包括Tony Patton对象)。到对象完整的路径在目录树里是唯一的。
目录树的每个节点包括一系列能够被检索和操控的属性。下面的术语在使用活动目录时很有用。
- 目录:用来保存信息的信息源。
- 活动目录架构:用来定义目录对象的属性。它类似于用来定义数据库结构的数据库架构。
现在让我们把主要精力转到如何使用活动目录上吧。
通过代码访问目录
.NET框架为访问活动目录提供了System.DirectoryServices命名空间。它使用活动目录服务接口(Active Directory Services Interfaces,ADSI)技术,微软也向其他很多网络提供商提供这个接口。这个命名空间包括两个组件类:
- DirectoryEntry:用来使用活动目录层次里单独的节点或者对象。它要与helper类一起使用才能操控目录资源和浏览资源树。你可以创建、删除、重命名、移动子节点,并枚举子节点。
- DirectorySearcher:让你使用轻型目录访问协议(Lightweight Directory Access Protocol,LDAP),它是唯一能够支持目录搜索的ADSI提供程序。你可以用DirectoryEntry类来使用搜索的结果。
尽管上面不是命名空间所包含的所有类,但是它们是最重要和最常用的两个。下面列表A里的C#代码用来访问我网络上的活动目录:
DirectoryEntry de = new DirectoryEntry();
de.Path = "LDAP://192.168.1.1/CN=Users;DC=DomainName";
de.Username = @"DomainNameUserName";
de.Password = "Password";
下面列表B里是相应的VB.NET代码:
Dim de As DirectoryEntry
Set de = New DirectoryEntry()
de.Path = "LDAP://192.168.1.1/CN=Users;DC=DomainName"
de.Username = @"DomainNameUserName"
de.Password = "Password"
这些代码让你能够访问活动目录,这样你就可以使用目录对象。你可能注意到路径用的是LDAP。ADSI包括下面这四个目录服务提供程序(我还提供了每个程序的句法):
- Windows 2000或Windows XP:WinNT://path
- LDAP:LDAP://path
- Novell NetWare目录服务:NDS://path
- Novell NetWare 3.x:NWCOMPAT://path
注意:使用活动目录一定要求安装好ADSI SDK或者ADSI运行库之后,才能够创建使用这一功能的应用程序。Windows 2000和XP默认就已经安装了它们。我们把上面的示例代码进行了扩展,以访问对象的所有属性,见下面的列表C:
DirectoryEntry de = new DirectoryEntry("LDAP://192.168.1.1/CN=Users;DC=DomainName");foreach(string key in de.Properties.PropertyNames) {
Console.WriteLine(key + " = ");
foreach(Object obj in de.Properties[key])
Console.WriteLine(obj);
}