现在的位置: 首页 > 综合 > 正文

Active Directory编程详解

2013年10月14日 ⁄ 综合 ⁄ 共 5853字 ⁄ 字号 评论关闭

24.4  Active Directory编程

要开发Active Directory程序,必须导入System.DirectoryServices命名空间。还必须引用System.DirectoryServices程序集。使用这个程序集中的类可以查询对象、查看和更新属性,搜索对象,把对象移动到其他容器对象中等。在下面的代码段中,简单的C#控制台应用程序说明了如何使用System.DirectoryServices命名空间中的类。

本节将介绍:

       System.DirectoryServices命名空间中的类

       连接Active
Directory
的处理方式:绑定

       获取目录项,创建新对象,并更新已有的项目

       搜索Active
Directory

24.4.1  System.DirectoryServices命名空间中的类

表24-1列出了System.DirectoryServices命名空间中的主要类。

  24-1

  

DirectoryEntry

这个类是System.DirectoryServices命名空间中的主类。这个类的对象表示Active
Directory
库中的一个对象。使用这个类可以绑定对象,查看和更新属性。对象的属性都放在PropertyCollection中。PropertyCollection中的每个元素都有一个PropertyValueCollection

DirectoryEntries

DirectoryEntriesDirectoryEntry对象的一个集合。DirectoryEntry对象的Children属性返回DirectoryEntries集合中的一个对象列表

DirectorySearcher

这个类主要用于用指定的属性搜索对象。要定义该搜索,可以使用SortOption类和枚举SearchScopeSortDirection ReferalChasingOption。搜索的结果是一个SearchResultSearchResultCollection。也可以得到ResultPropertyCollection  ResultPropertyValueCollection对象

24.4.2  绑定

要获得Active Directory中一个对象的值,必须连接Active Directory服务。这个连接过程称为绑定,绑定路径如下所示。

LDAP://dc01.athenaproject.com/OU=Development, DC= AthenaProject, DC=Com

在绑定过程中,可以指定下述内容:

       指定提供程序使用的协议(protocol)

       域控制器的服务器名(server
name)

       服务器过程的端口号(port
number)

       对象的显名(distingunshed
name)
,以标识要访问的对象。

       如果需要访问Active
Directory
的用户不是运行当前进程的账户,则提供用户名和密码。

       如果需要加密,应指定authentication类型

下面详细介绍这些内容。

1. 协议

绑定路径的第一部分指定ADSI提供程序。该提供程序是一个COM服务器;prog-id的标识信息在注册表的HKEY_CLASSES_ROOT下。Windows XP附带的提供程序如表24-2所示。

2. 服务器名

在绑定路径中,服务器名在协议的后面。如果用户登录到Active Directory域上,服务器名就是可选的。如果不提供服务器名,就会发生无服务器绑定操作,此时Windows Server 2003会在域中查找与用户绑定过程相关的、“最好的”域控制器。如果站点中没有服务器,就使用查找到的第一个域控制器。

无服务器的绑定如下所示:

LDAP://OU=SalesDC=AthenaProjectDC=Local

  24-2

    

    

LDAP

LDAP服务器,例如Exchange目录和Windows
2000 Server
Windows Server 2003 Active Directory服务器

GC

GC用于访问Active Directory中的全局目录。它也可以用于快速查询

IIS

使用IISADSI提供程序,可以在IIS目录中创建和管理新网站

WinNT

要访问旧Windows NT 4域的用户数据库,可以使用WinNT ADSI提供程序。NT4用户只有几个属性没有改变。也可以使用这个协议绑定Windows
2000
域,但这里也限制了可用于NT4的属性

NDS

这个progID用于和Novell
Directory Services
通信

NWCOMPAT

使用NWCOMPAT可以访问旧的Novell目录,例如Novell
Netware 3.x

3. 端口号

在服务器名的后面,可以指定服务器过程的端口号,其语法是:xxx。LDAP服务器的默认端口号是端口389: LDAP://dc01.globalknowledge.net:389。Exchange服务器使用的端口号与LDAP服务器一样。如果在同一个系统上安装了Exchange服务器,例如用作Active Directory的域控制器,就可以配置另一个端口。

4. 显名

在路径中指定的第四部分是显名(distinguished name,DN)。显名是一个惟一的名称,标识要访问的对象。在Active Directory中,可以使用基于X.500的LDAP语法,指定对象的名称。

例如有一个显名:

CN=Christian Nagel, OU=Consultants, DC= AthenaProject, DC=local

这个显名指定域AthenaProject.local中域组件(Domain Component,DC) AthenaProject的组织单元(Organizational Unit,OU) Consultants的公共名称(Common Name,CN) Christian Nagel。最右边的部分是域的根对象。该名称必须符合对象树中的分层方式。

显名的字符串表示的LDAP规范在 RFC 2253( http://www.ietf.org/rfc/rfc2253.txt)上。

(1) 相对显名

相对显名(RDN)用于引用容器对象中的对象。使用RDN时,不需要指定OU和DC,有一个公共名称就足够了。CN=Christian Nagel就是组织单元中的一个相对显名。如果已经引用了一个容器对象,要访问其子对象,就可以使用相对显名。

(2) 默认的命名环境

如果在路径中没有指定显名,绑定过程就会使用默认的命名环境(default naming context)。使用rootDSE可以读取默认命名环境。LDAP 3.0把rootDSE定义为目录服务器中目录树的根。例如

LDAP://rootDSE

或:

LDAP://servername/rootDSE

通过列举rootDSE的所有属性,将获得没有指定名称时可以使用的defaultNamingContext信息。schemaNamingContext 和 configurationNamingContext指定了用于访问模式所需要的名称和Active Directory库中的配置。

通过下面的代码可获得rootDSE的所有属性:

using (DirectoryEntry de = new DirectoryEntry())

{

   de.Path = "LDAP://platinum/rootDSE";

   de.Username = @" platinum\christian";

   de.Password = "password";

 

   PropertyCollection props = de.Properties;

   foreach (string prop in props.PropertyNames)

   {

      PropertyValueCollection values = props[prop];

      foreach (string val in values)

      {

         Console.Write(prop + ": ");

         Console.WriteLine(val);

      }

   }

}

这个程序显示了默认的命名环境(defaultNamingContext DC=eichkogelstrasse、 DC=local),用于访问模式的环境(CN=Schema、 CN=Configuration、 DC=eichkogelstrasse、 DC=local)和配置的命名环境(CN=Configuration、 DC=eichkogelstrasse、 DC=local),如图24-9所示。

  24-9

(3) 对象标识符

每个对象都有一个全局惟一的标识符GUID。GUID是一个惟一的128位数字,您可能已经在COM开发中了解了它。可以使用GUID绑定一个对象。这样,即使对象移动到另一个容器中,也可以得到该对象。GUID在创建对象时生成,且总是保持不变。

使用DirectoryEntry.NativeGuid可以得到GUID的字符串表示。这个字符串表示就可以用于绑定对象。

下面的示例显示了一个无服务器绑定的路径名称,它绑定到GUID代表的一个特定对象上:

LDAP://<GUID=14abbd652aae1a47abc60782dcfc78ea>

 (4)  Windows NT域中的对象名

WinNT提供程序不允许在绑定字符串的名称部分使用LDAP语法。在这个提供程序中,对象用ObjectName、ClassName指定。Windows NT域的有效绑定字符串如下:

WinNT:

WinNT://DomainName

WinNT://DomainName/UserName, user

WinNT://DomainName/ServerName/MyGroup, group

user和group后缀指定可以访问类型为user或group的对象。

5. 用户名

有时,在访问目录时,必须使用一个非当前进程的用户名(也许这个用户没有访问Active Directory所必须的许可),此时必须为绑定过程显式指定用户证书(user credential)。Active Directory提供了许多方式来设置用户名。

(1) Downlevel登录

使用downlevel登录,用户名可以用Windows 2000以前的域名来指定:

domain\username

(2) 显名

也可以用user对象的显名来指定用户,例如:

CN=Administrator CN=UsersDC=athenaprojectDC=local

(3)  User Principal Name (UPN)

对象的UPN用userPrincipalName属性来定义。系统管理员可以在Active Directory Users and Computers工具中User属性的Account选项卡上,用登录信息来指定UPN,注意这不是用户的电子邮件地址。

这些信息也惟一地标识了用户,可以用于登录:

Nagel@ athenaproject.local

6. 身份验证

为了给身份验证进行安全的加密,也可以指定身份验证(authentication)类型。身份验证可以用DirectoryEntry类的AuthenticationType属性设置。可以指定其值为AuthenticationTypes枚举中的一个值。因为枚举是用属性[Flags]标识的,所以可以指定多个值。其可能的值有:对发送的数据进行加密的ReadonlyServer,它指定只需要读取访问,Secure表示安全的身份验证。

7. DirectoryEntry类绑定

System.DirectoryServices.DirectoryEntry类可以用于指定所有的绑定信息。可以使用默认的构造函数,用Path、Username、Password和 AuthenticationType属性定义绑定信息,或者把这些信息传递给构造函数:

DirectoryEntry de = new DirectoryEntry();

de.Path = "LDAP://platinum/DC=athenaproject, DC=local";

de.Username = "nagel@ athenaproject.local";

de.Password = "password";

 

// use the current user credentials

DirectoryEntry de2 = new DirectoryEntry(

                            "LDAP://DC= athenaproject, DC=local");

即使成功地构造了DirectoryEntry对象,也并不意味着绑定成功了。在第一次读取属性时进行绑定,可以避免不必要的网络流通量。对象是否存在,或者指定的用户证书是否正确,都可以在第一次访问该对象时确定。

24.4.3  获取目录项

前面介绍了如何指定Active Directory中对象的绑定属性,下面要读取对象的属性。在下面的示例中要读取用户对象的属性。

DirectoryEntry类的一些属性可以提供对象的信息,即Name、Guid和 SchemaClassName属性。第一次访问DirectoryEntry对象的属性时,会执行绑定操作,并填充底层ADSI对象的缓存。后面将详细讨论这些。其他属性可以从缓存中读取,同一对象的数据不需要通过与服务器的通信来获得。

在本例中,用组织单元Wrox Press中的公共名称Christian Nagel访问一个用户对象:

using (DirectoryEntry de = new DirectoryEntry())

{

   de.Path = "LDAP://platinum/CN=Christian Nagel, " +

             "OU=Wrox Press, DC=athenaproject, DC=local";

 

   Console.WriteLine("Name: " + de.Name);

   Console.WriteLine("GUI

抱歉!评论已关闭.