普通目录及其面临的困难

谈到计算机目录及其相关技术,总能让我们想到无时不在使用的文件系统目录、灵巧实用的专用工具集目录、海量存储的网络资源目录等等。是的,这是一个异常熟悉的领域:在文件系统目录里,我们存储文件及其大小、创建日期、类型等信息;在诸如记事本类的专用工具集目录里,我们存放日程安排、联系方式、人员地点等信息;在网络资源目录里,我们以分层架构存放网络上所有对象的相关资料,这些对象包罗了网络里使用的各种资源:共享目录、共享打印机、应用程序、服务、服务器、用户帐号、组、域…可以这样说,从使用计算机的那一刻起,我们就从未离开过目录!曾经,这样的目录让我们随心所欲地处理我们的资源!

然而,正是这样的目录,在Internet下却面临许多麻烦:种类繁多、数量日增的目录让我们很难准确定位想要的资源;系统目录、应用程序特定目录、网络资源目录中到底谁存储了我们需要的信息?如何能用一致的方式登录这些不同的资源?怎样能轻松地维护不同系统上的远程资源?能否通过可视化的程序界面在这些资源间交互?

初识Active Directory活动目录

要解决这些问题,你可以使用Micrsoft提供的活动目录Active Directory 对象,它提供一种构造复杂计算机网络的简单方法,用来存储公共文件夹、对象信息、打印机、服务等数据; Active Directory的适用范围很大,它可以用在小自一台计算机,一个计算机网络,大至数个广域网络(WAN)的结合。它可以包含这个范围中所有的对象:文件、打印机、应用程序、服务器、域,以及用户等等。与普通意义上的目录不同的是, Active Directory活动目录以分层树状结构排列成节点树,每个节点表示网络上的一个资源或服务,并且包含一组可检索和操作的属性。Active Directory 是提供复杂网络统一视图的 Windows目录服务,它减少了开发人员必须处理的目录和命名空间的数量。

Directory Service目录服务

同时,专门针对Active Directory活动目录的Directory Services目录服务则让目录中的信息可用,Directory Service(目录服务)是让用户很容易地在目录内寻找到所需要的对象的一种服务。通过对Active Directory中数据的整理、规划存储,目录服务使得目录中的信息可用,真正让目录"活动"起来了。理由很明显,Internet网络、WAN局域网络里海量存储的数据往往让你迷失不知所措,再加上这些存放的资料不加以整理,想找到您需要的资料谈何容易!相反地,如果经过适当的规划,事先有系统地去整理这些资料,那就可以在需要时方便快速地寻找到你所要的对象。这样的例子现实生活中也随处可见:查号台算得上是一种目录服务;在Internet上的搜索引擎提供的查询功能究其实也是一种目录服务。目录服务不仅广义地包括了上述的各种目录(共享目录、共享打印机、应用程序、服务,网络服务器、用户帐号、计算机帐号、域、安全规则等等),更重要的它同时也是一种服务,让管理者、用户及应用程序都能利用目录中的资料处理这些对象。

其实,目录服务早就以不同的形式出现许多应用领域:一些操作系统如Microsoft的NT中的NTDS( Windows NT Directory Service), Novell 中的NDS(Novell Directory Service )等都整和了这种运用;另外,它也常集成在应用程序中,如Microsoft Exchange Server等。

作为Active Directory的广泛应用,Microsoft更是以Active Directory及其Service服务为整个分布式运算环境的基础。它可以包含并管理前述不同操作系统及应用程序相关的各种目录服务,提供用户、管理者,及程序开发者一个通用的目录服务,大大减少了企业的负担。

Active Directory支持的标准——走进ADSI

为实现活动目录服务,Active Directory支持了以下开放的标准:

LDAP轻型目录访问协议(Lightweight Directory Access Protocol)是用于访问Acitve Directory中数据的一个标准,它同时又是一个编程接口,提供API用来访问Active Directory活动目录;还有一个专门用于用户身份验证的标准是Kerberos协议,Windows 和Unix均支持这一协议以验证用户身份!

另外,为进一步简化程序方式访问Active Directory,Microsoft专门提供了ADSI(Active Directory Service Interface)活动目录服务接口语言,更使得编程人员可以更轻松地访问Active Directory的所有功能!使用ADSI,可以创建执行常见管理任务的应用程序,这些任务包括备份数据库、访问打印机和管理用户帐户等。ADSI 使管理员能够相对方便地定位和管理网络上的资源,不管网络的大小如何。

若要使用 ADSI 技术,在客户端计算机上必须提供有ADSI SDK或ADSI运行库,这可以通过安装 ADSI 2.5 或更高版本来实现。对于 Windows NT 5.0 版、Windows 2000 或 Windows XP,默认安装了 ADSI 2.5。如果使用的是以前版本的 Windows,则您可以自己从 Microsoft Web 站点安装该 SDK。

Active Directory架构

Active Directory架构(Schema)包含定义了各种形式的能够在Active Directory中使用的对象类(如共享打印机、共享目录等),它同时也定义了在Active Directory允许存在的各种属性以提供对象的附加信息,如Name、Guid标识等,这种定义目录对象、属性的方式与数据库架构定义数据库结构的方式大体相同。架构信息存储在 Active Directory 层次结构中,可以大大加快在大型目录上进行成员搜索的速度。Active Directory 使用架构定义可以访问网络节点的指定信息。架构提供了一种给存储在目录中的对象类型创建全局定义的方法,这些定义并赋予有意义的名称,如“用户”和“计算机”,更易于用户的访问识别。

DirectoryServices名字空间

.Net架构对Active Directory提供了丰富的支持功能,其命名空间 System.DirectoryServices包含的DirctoryEntry、DirectoryEntries以及DirectorySearcher等类库可与任何 Active Directory 服务提供程序(一种识别绑定协议并提供相关服务的程序,下面有专门阐述)一起使用,.NET 框架的这些支持使得操作具有 DirectoryEntry 和 DirectorySearcher 等组件的 ADSI 功能非常容易。

DirectoryEntry组件

DirectoryEntry 组件使从目录访问对象以及使用其数据和行为非常方便。当给 DirectoryEntry 组件指定一个 Active Directory 层次结构中的有效目录路径时,它返回可操作的 ADSI COM 对象,这些对象包括用户、计算机、服务、用户帐户和计算机的组织、文件系统以及文件服务操作。DirectoryEntry 类封装 Active Directory 层次结构中的节点或对象,使用此类库绑定到对象、读取属性和更新特性。DirectoryEntry 与帮助器类一起为生存期管理和导航方法提供支持,包括创建、删除、重命名、移动子节点和枚举子级。

可以将 DirectoryEntry 组件绑定到目录中的对象以执行管理任务,如修改属性或监视信息更改。可以使用 DirectoryEntry 组件自动执行常见管理任务,如添加用户和组、管理打印机以及设置网络资源的权限。这样,你可以使用 DirectoryEntry 组件与企业中任何目录系统上的任何资源进行交互。可以向层次结构添加新的节点。当然,如果需要更改 Active Directory 对象的属性值,你必须拥有所绑定到对象的管理权限。

在创建新的对象时,DirectoryEntry 组件会用到 Active Directory Schema 架构。这时你需要指定一个先前已存在的架构名,并将该对象与之关联。

DirectorySearcher组件

DirectorySearcher 组件使用Active Directory架构信息在目录中执行搜索并获得节点的属性并返回 SearchResult 的实例,这些实例包含在 SearchResultCollection 类的实例中。SearchResult 的实例与 DirectoryEntry 的实例非常类似。明显的差异在于每次访问新对象时,DirectoryEntry 都从 Active Directory 层次结构中检索其信息,而 SearchResult 的数据已经存在于用 DirectorySearcher 执行的查询返回的 SearchResultCollection 中。SearchResult 中只存在那些在查询中通过 DirectorySearcher.PropertiesToLoad 属性的集合指定的属性。

可以使用 DirectorySearcher 类对使用轻量目录访问协议(Lightweight Directory Access Protocol,LDAP)的 Active Directory 层次结构进行搜索以查找特定的服务或对象;可以基于大型目录中对象的属性 (Rich Query) 执行查询,以便按其一个或多个属性值查找特定的对象;可以封装层次结构中的节点,并操作或查询其属性。DirectorySearcher 组件的实例需要 LDAP 提供程序以便对 Active Directory 层次结构执行多格式查询。LDAP 是系统提供的唯一一种支持搜索的 Active Directory 服务接口 (ADSI) 提供程序。

目录服务提供程序

可以使用 DirectoryEntry 组件访问的每种目录系统类型都具有一种特定的目录协议(称为“服务提供程序”),此协议允许您访问和处理该目录的内容。创建ADSI可使开发人员通过单个接口访问所有的协议,从而可以方便地在这些协议之间进行切换。

下表列出了可以访问的服务提供程序以及每种服务提供程序的标识符。

服务提供程序 路径标识符
Windows NT 5.0 版、Windows 2000 或 Windows XP WinNT://path
轻量目录访问协议(LDAP) LDAP://path
Novell NetWare 目录服务 NDS://path
Novell Netware 3.x NWCOMPAT://binderyServer/TopHat

每种服务提供程序为您提供一组不同的可访问和操作的对象以及关联数据和行为。这些对象与该命名空间的目录树中的项和资源对应。很多提供程序具有相同的对象。例如,所有提供程序授予您访问组对象(表示一个组帐户)和用户对象(表示一个用户帐户)的权限。

对于 Windows NT 服务提供程序,您可以访问域、计算机、打印队列和会话。对于 LDAP 提供程序,您可以访问组织、地址和"根 DS 项"(rootDSE) 对象。LDAP把rootDSE定义为目录服务器中目录树的根。根 DS 项是一组必需的操作属性,用户可以读取这些属性以找出目录和服务器的基本特征:如读取默认命名环境名(default naming context), rootDSE 仅对 LDAP 提供程序是必需的。

绑定及路径

当创建DirectoryEntry组件的实例时,需要指定所使用的服务提供程序的类型以及要操作的对象,并与Active Directory连接,这个过程称为“绑定”。这时,你需要指定所使用的协议(LADP、WinNT等),即服务提供程序指示符。当前的一些服务提供程序包括 Internet 信息服务 (IIS)、轻量目录访问协议 (LDAP)和 WinNT等。随后你可能需要指定计算机所在的域名、组名以及计算机名,如果没有显示式指定域名(服务器名),系统就会在整个域中查找与用户绑定过程相关的域控制器,并且使用所找到的第一个域控制器。这样,WinNT下的绑定语法大致为:

1.WinNT://MyDomain/Group

2.WinNT://MyDomain/MyComputer/aPrinter/

这个过程中,可能需要指定路径信息,类DirectoryEntry的Path属性唯一地标识网络环境中的路径信息,设置该属性将从目录存储区检索新项,它不更改当前绑定的项的路径。同绑定类似,Path 属性的语法取决于服务提供程序,在WinNT 下连接到计算机上的组语法为:WinNT://domain/computer/group;而IIS下连接到Web目录则为:IIS://LocalHost/W3SVC/1/ROOT/web-directory-name。

ADSI可实现的操作

依赖于.Net架构类库的强大支持,使用ADSI使以下操作变得简单可行:

1、一次登录可处理不同的目录。DirectoryEntry 组件类提供用户名和密码属性,可以在运行时输入这些属性并与绑定到的 Active Directory 对象进行通讯。

2、通过给用户提供各种要使用的协议,使用单个应用程序编程接口 (API) 即可在多个目录系统上执行任务。

3、对目录系统执行"多格式查询"。ADSI 技术允许通过指定两种查询语言,即 SQL 和 LDAP,来搜索对象。

4、通过访问 Active Directory 树,访问和使用用于管理和维护各种复杂网络配置的单个分层结构。

5、将目录信息与数据库(如 SQL Server)进行集成。只要 DirectoryEntry 路径使用 LDAP 提供程序,就可以将它用作 ADO.NET 连接字符串。

实 例

运用上面的知识,以下创建了一个Windows Forms程序实例,它可以列出本地计算机上的用户、组和服务。程序实现时,请拖放TreeView控件到窗体上,设置其名为viewPC(它将在程序中提供三个顶级节点,各个节点分别用于用户User、组Group和服务Services。每个二级节点都将代表一个在您的计算机上注册的用户、组或服务。每个用户、组和服务都具有两个子节点,一个用于其 Active Directory 路径Path,另一个用于其属性Porperties);同时,请添加System.DirectoryServices.dll引用。并从组件中拖入 DirectoryEntry 组件,配置 DirectoryEntry 组件属性,设置其名Name 属性为 entryPC。将 DirectoryEntry 组件的 Path 属性设置为 WinNT://研发中心/Webserver。(这里,“研发中心”是笔者所在的组名,“Webserver”则是笔者所使用的计算机服务器名,你可能需要修改它们)。运行程序,就将可视化地列出指定计算机上的所有用户、组和服务,展开这些节点,将罗列出它们各自的路径及属性。

主要源代码如下:

private void Form1_Load(object sender, System.EventArgs e)
		{
			TreeNode users=new TreeNode("Users");
			TreeNode groups=new TreeNode("Groups");
			TreeNode services=new TreeNode("Services");
			viewPC.Nodes.AddRange(new 
TreeNode[]{users,groups,services});		
foreach(DirectoryEntry child in entryPC.Children)
{
	TreeNode newNode=new TreeNode(child.Name);
	switch(child.SchemaClassName)
	{
		case "User":
			users.Nodes.Add(newNode);
			break;
		case "Group":
			groups.Nodes.Add(newNode);
			break;
		case "Service":
			services.Nodes.Add(newNode);
			break;
	}
	try
	{		AddPathAndProperties(newNode,child);
	}
	catch(Exception ex)
	{
		MessageBox.Show(ex.Message);
	}
}
}
//以下函数实现路径及属性的添加功能
private void AddPathAndProperties(TreeNode node,DirectoryEntry entry)
{
	node.Nodes.Add(new TreeNode("Path:"+entry.Path));
	TreeNode propertyNode=new TreeNode("Properties");
	node.Nodes.Add(propertyNode);
	foreach(string propertyName in entry.Properties.PropertyNames)
	{	string
	oneNode=propertyName+":"+entry.Properties[propertyName][0].ToString();
	    propertyNode.Nodes.Add(new TreeNode(oneNode));
	}
}

程序拓展

运行以上程序段将列举出本地机上注册的用户、组、服务及其属性。要列举远程计算机的相应属性,你需要更改DirectoryEntory组件的Path属性为远程计算机名,比如"销售事业部"是笔者所在公司的一个远端工作组,"Xsb1"是这个组中的一台计算机,设置Path=WinNT://销售事业部/Xsb1,就可以列出该机所配置的相关属性。不过,要保证这一功能的实现,你需要确保此远程计算机(如Xsb1)启动了Guest客户访问权限,否则将引发"访问被拒绝"异常;同时,你也需要确保该远程机能支持Active Directory活动目录,即提供了ADSI SDK运行库,否则,将引发"计算机名无效"异常。

运行环境

程序在:Windows XP中文操作系统、Microsoft .Net Frameworks框架、Visual Studio.Net 正式

中文版下调试通过

参考资料:《C#高级编程》、《Visual studio.net深入编程》、《.Net数据服务c#高级编程》、Vs.net帮助文档

posted on 2008-09-27 22:17  yxbsmx  阅读(396)  评论(0编辑  收藏  举报