转至繁体中文版     | 网站首页 | 图文教程 | 资源下载 | 站长博客 | 图片素材 | 武汉seo | 武汉网站优化 | 
最新公告:     敏韬网|教学资源学习资料永久免费分享站!  [mintao  2008年9月2日]        
您现在的位置: 学习笔记 >> 图文教程 >> 软件开发 >> VB.NET程序 >> 正文
AD & ADSI入门         ★★★★

AD & ADSI入门

作者:闵涛 文章来源:闵涛的学习笔记 点击数:1918 更新时间:2009/4/23 18:59:24
AD简介 Active Directory(以下简称AD)可以认为是一个大的层次结构数据库,集中存储的内容必须遵循AD当前所定义的Schema。我觉得AD中最重要的内容就是Schema,然后是ADSI。   Schema定义了数据存储的格式。包括类(classSchema),分为抽象类(Abstract)、附属类(Auxiliary) 和结构类(Structure)三种;属性(attributeSchema),分为单值和多值属性;以及类和属性之间的关系,分为可选属性和必要属性。AD中的Schema相当于全局的Catalog,在整个AD的forest中是全局唯一的,任何的修改都会被同步。所以有关Schema的修改需要有Schema Administrators的权限。而且Schema的内容只能增加,不能删除,过程是不可逆的,最多只能禁止一些属性或者类,而且还有诸多限制,详见文档。   在AD中存储的数据被当作一个一个的对象,每一个对象是一个classSchema的实例。都有一个唯一的路径访问。AD中对象的路径由所支持的Provider决定,Windows 2000默认的Provider有四个,安装IIS的话会增加一个IIS的Provider,对IIS进行管理。通常使用比较多的是LDAP,可以通过这个Provider针对域用户以及其他扩展信息进行访问和管理。WinNT是针对NT4的帐号管理,估计是向下兼容。另外两个是对Netware的DN的访问,对我们而言不太会用到,不赘述了。   ADSI(Active Directory Service Interface)是用来对AD中存储数据的访问接口,我认为他是一个架空的框架,与具体的数据访问无关,只是给上层应用提供一个统一的接口。实际工作的就是Provider,应当是Provider访问数据,然后包装成ADSI要求的形式,这些工作对用用户来说完全透明。 另一个比较爽的地方是ADSI提供了比较好的扩展的方式,你能够非常容易的增加新的类,或者给已有的类增添新的方法。 需要解释一下,虽然ADSI和AD经常一起出现,但是AD和ADSI是两码事,ADSI不仅仅能访问AD,还可以访问IIS以及Netware所存储的数据。你只要按照要求提供相应的Provider,ADSI可以干任何事情。     AD编程 AD的编程到目前来看涵盖的内容非常多,从最粗糙的使用ADSI对AD中已有的数据访问,到比较高级的扩展AD。我认为扩展AD才是这部分编程中比较重要的内容,因为针对任何具体的应用多绘有自己特定的信息,而应用AD主要是为了利用MS提供的安全性以及分布式存储,如果将这两方面结合起来,就需要为了自身的应用对AD进行扩展。 如果需要为已有的类(接口类)添加方法,那么需要编写AdsExtension类;如果需要在AD中存储扩展信息,就需要修改Schema,增加新的类(classSchema)或者属性(attributeSchema);更进一步的话,完全可以自己实现一个Provider,实现自己的查询和数据存储的方式,这一部分内容已经不仅仅局限于AD了。
  • 通过ADSI访问AD
    通过ADSI访问AD比较简单,实际上是应用WinNT和LDAP这两个Provider。除了通用接口IAds、IAdsContainer、IAdsDirectorySearch等以外,Windows默认提供了一些接口类如IAdsUser、IAdsGroup,当安装了一些基于AD的服务之后,又会增加一些专有接口,如安装Exchange 2000之后,会出现Person,同时扩展了User。     在使用AD的过程中比较重要的一个问题是访问者的权限,如果使用GetObject的方式操作,那么应用程序是以当前登录用户的权限访问AD,很多的写操作是被拒绝的。使用IAdsOpenDSObject->OpenDSObject可以指定操作对象的用户,当然这就需要实现得到指定用户的口令。     第二个需要注意的地方就是AD的Path,有两个最常用的前缀(姑且这么叫吧):CN(Common Name)和DC(Domain Controller)。另外对于LDAP从左到右范围增大,而WinNT从左到右范围是减小,比如访问我的帐号,路径分别为LDAP://CN=mittermeyer,CN=Users,DC=cn,DC=corp,DC=company,DC=com,WinNT://cn.corp.company.com/Users/mittermeyer。另外据说AD是区别大小写的,我看下来他有一种数据类型是区别大小写的字符串,但是路径这里好像无所谓,CN=和cn=都行。     第三个需要注意的地方就是查询语法。查询的话,一共提供了两种方式,一个是IAdsSearchDirectory接口,IAdsDirectorySearch完成查询过程和处理查询结果的全部工作,我个人认为这种方式不太适合VB的程序;另一种方式是使用ADO。AD针对ADO有一个Provider(ADsDSOObject),使用这种方式返回一个ADO.Recordset,处理结果和关系型数据库的查询完全一致,这种方式VB比较容易上手。ADO的方式查询可以使用SQL的语法,也可以使用LDAP的语法;而IAdsDirectorySearch只能使用到的是LDAP的语法。       这一部分比较有趣的是扩展接口,就是写一个接口作为已经存在的接口类的扩展。扩展接口本身只是继承IDispatch就可以了,但是如果需要支持后期绑定,那么还需要实现IAdsExtension所要求的一系列方法,看上去是模板,就是一个套路,所以这部分工作还是比较简单的。
    关键是把自己编写的接口和已经存在的接口类关联,嘿嘿!也很简单,只要在注册表里加一项就可以了。(MS想到的方法总是比较容易理解,不过在整体框架那里还是花了很多心思的,所以架子有了扩展就容易了。)例如:以及下就是Exchange加的对User地扩展,它表明Exchange针对User有一个扩展的CoClass--Mailbox,其中包含了两个接口IMailRecipient和IMailboxStore。 [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\ADs\Providers\LDAP\Extensions\User] [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\ADs\Providers\LDAP\Extensions\User\{25150F21-5734-11D2-A593-00C04F990D8A}]
"Interfaces"=hex(7):7b,00,32,00,35,00,31,00,35,00,30,00,46,00,34,00,31,00,2d,\
  00,35,00,37,00,33,00,34,00,2d,00,31,00,31,00,44,00,32,00,2d,00,41,00,35,00,\
  39,00,33,00,2d,00,30,00,30,00,43,00,30,00,34,00,46,00,39,00,39,00,30,00,44,\
  00,38,00,41,00,7d,00,00,00,7b,00,32,00,35,00,31,00,35,00,30,00,46,00,34,00,\
  30,00,2d,00,35,00,37,00,33,00,34,00,2d,00,31,00,31,00,44,00,32,00,2d,00,41,\
  00,35,00,39,00,33,00,2d,00,30,00,30,00,43,00,30,00,34,00,46,00,39,00,39,00,\
  30,00,44,00,38,00,41,00,7d,00,00,00,00,00
 
  • 扩展Schema
    首先,我们知道attributeSchema和classSchema都存储在同一个层次下,我们可以通过这样的路径访问:LDAP://computername/Schema 之下(另外一种访问路径是CN=Schema,CN=Configuration,<DC=forestroot>),所以在这个Container下我们可以枚举到整个AD中所有的attributeSchema和classSchema。但是我发觉有一个有趣的现象,如果不是以域用户的身份去访问,那么不能得到全集,获得的是Abstract Class和相关的属性,无法得到Structure Class,例如:User。     其次,针对attributeSchema和classSchema都有一些特性:
    OID(governsID),LDAP所需要的对象的唯一表示符,这是一个字符串,但是不同于GUID根据本机信息生成,而是逐级分配的属性结构,最上层由ISO分配,逐级授权,所以很麻烦。MS提供了一个工具OIDGEN.exe,随Windows 2000的Resource Kit发布,我不知道即使是用这样的工具生成的新ID能否运行在实际的扩展系统中,还是必须通过MS的认证。
    schemaIDGUID,用于访问控制目录中控制访问这个类的对象。通过这个ID而不是名称来访问类的对象实例。GUID还是非常好处理的,可以通过Windows自身的API获得。
    其他的就是各类名称(cn,LDAPDisplayName,adminDisplayName),在不同的工具或者场合显示区别类或者属性,这些名字只要保证全局唯一即可。此外classSchema和attributeSchema各有一些特定的必备属性。       扩展Schema包括以下几部分的工作:新增/禁止attributeSchema,新增/禁止classSchema,修改Property与classSchema的关系。
    新增attributeSchema和classSchema,通过IAdsContainer.Create,在Schema存储的路径下新建子节点,然后给必要的属性赋值,最后提交即可。
    禁止attributeSchema和classSchema,可以通过“废弃”的方式禁止一个现存的类或者属性。即获得这个classSchema或者attributeSchema,将他的isDefunct属性置为True即可;反之只要将isDefunct属性置为False即可恢复。当然这个操作也存在一系列的限制,例如:禁止一个属性,那么将阻止创建所有所有必须包含该属性的类的实例。
    修改Property与classSchema的关系,因为决定每一个classSchema中包含哪些attributeSchema,其实是指定classSchema的“mustContain”和“mayContain”,这两个多值属性(字符串数组)分别表示表示所包含的必要属性和可选属性。反过来,可以通过IAdsClass.MandantoryProperties和IAdsClass.OptionalProperties读取。  
  • 实现Provider
    暂时没有研究。     实例
  • 枚举对象。下面这个例子枚举了所有通过RC的接口添加到AD中的用户组和帐号。此例中IAdsContainer.Filter为一个需要筛选的类名数组,如果为空,则表示返回所有类型的对象。
Public Function EnumGroups() As VBA.Collection
    Dim adDomain As IADsContainer
    Dim adGroup As IADsGroup
    Dim nResult As VBA.Collection
   
    If m_sAdmin <> vbNullString Then
        Set adDomain = m_adRoot.OpenDSObject("LDAP://" & m_sExchServer & "/CN=Users," & m_sDomain, _
                                    m_sAdmin, m_sAdminPwd, ADS_SECURE_AUTHENTICATION)
    Else
        Set adDomain = GetObject("LDAP://CN=Users," & m_sDomain)
    End If
    If adDomain Is Nothing Then Exit Function
   
    Set nResult = New VBA.Collection
    adDomain.Filter = Array("group","user"”)
   
    On Error Resume Next
    Dim sName As String
    Dim sType As String
    For Each adGroup In adDomain
        sName = Right(adGroup.Name, Len(adGroup.Name) - 3)  '''' filter "CN="
        Debug.Print sName
        sType = adGroup.Get(cPropCustomType)
        If Err.Number = 0 And sType = cTypeRC Then
            nResult.Add sName, sName
        End If
        Err.Clear
    Next
    Set EnumGroups = nResult
End Function
 
  • 添加一个用户以及用户相关的邮箱,这是一个相对复杂的利用ADSI的示例,其他类似的操作就不赘述了。这里用到的就是ADSI和Exchange针对ADSI中IAdsUser对象的扩展。斜体的那一段代码颇值得回味,在VB中非常简单的一句话,背后有一套复杂的逻辑。
    添加用户组和组邮箱的操作类似,不同的是组邮箱不是一个物理邮箱,而是一个邮箱列表,通过IMailRecipient.MailboxEnabled使之有效即可。
'''' add new user to Domain and create mailbox for it
Public Function AddAccountEx(ByVal sAccount As String, ByVal sFullName As String, ByVal sDesc As String, _
                            ByVal sPassword As String) As Long
    Dim adDomain As IADsContainer
   
Dim adNewUser As IADsUser
    Dim oMailStore As CDOEXM.IMailboxStore
   
Dim oExchServer As CExchageManager
   
    If m_sAdmin <> vbNullString Then
        Set adDomain = m_adRoot.OpenDSObject("LDAP://CN=Users," & m_sDomain, _
                                    m_sAdmin, m_sAdminPwd, ADS_SECURE_AUTHENTICATION)
    Else
        Set adDomain = GetObject("LDAP://CN=Users," & m_sDomain)
    End If
 

[1] [2]  下一页


[学习帮助]如图所示,△ABE和△ADC是△ABC分别沿着AB、AC边翻…  [办公软件]VBA中初始化ADO连接的几种方法
[网络安全]计算机无法上网的罪魁祸首—(宰了)删除adware.roo…  [Sql Server]Sql精妙语句--各种求值函数
[Web开发]ADO.NET操做数据库  [平面设计]Flash loadMovie/loadMovieNum 使用详解
[平面设计]功能超强的GIF动画制作软件─Ulead Gif Animator  [平面设计]AutoCAD常用快捷命令(外加中文说明)
[平面设计]AutoCAD常用快捷命令(字母类,外加中文说明)  [平面设计]AutoCAD快捷命令介绍
教程录入:mintao    责任编辑:mintao 
  • 上一篇教程:

  • 下一篇教程:
  • 【字体: 】【发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口
      注:本站部分文章源于互联网,版权归原作者所有!如有侵权,请原作者与本站联系,本站将立即删除! 本站文章除特别注明外均可转载,但需注明出处! [MinTao学以致用网]
      网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!)

    同类栏目
    · C语言系列  · VB.NET程序
    · JAVA开发  · Delphi程序
    · 脚本语言
    更多内容
    热门推荐 更多内容
  • 没有教程
  • 赞助链接
    更多内容
    闵涛博文 更多关于武汉SEO的内容
    500 - 内部服务器错误。

    500 - 内部服务器错误。

    您查找的资源存在问题,因而无法显示。

    | 设为首页 |加入收藏 | 联系站长 | 友情链接 | 版权申明 | 广告服务
    MinTao学以致用网

    Copyright @ 2007-2012 敏韬网(敏而好学,文韬武略--MinTao.Net)(学习笔记) Inc All Rights Reserved.
    闵涛 投放广告、内容合作请Q我! E_mail:admin@mintao.net(欢迎提供学习资源)

    站长:MinTao ICP备案号:鄂ICP备11006601号-18

    闵涛站盟:医药大全-武穴网A打造BCD……
    咸宁网络警察报警平台