使用ASP開發(fā)NT目錄服務(wù)會(huì)出現(xiàn)的一些問(wèn)題(I)
有關(guān)ADSI的資料真是難找,技術(shù)雖然很好,可惜300多頁(yè)的SDK我可真看不動(dòng) 要是哪位大俠有空的話,能夠幫我翻譯就好了,呵呵。 現(xiàn)在只好將就著翻譯一些短小的文章了,哎。匆忙之間翻譯成的,錯(cuò)誤肯定不 少,還希望大家諒解。 使用到的技術(shù)還是我前面提到的ADSI,這一節(jié)的重點(diǎn)放在操縱目錄樹上。 目錄服務(wù)(DN)在貫穿了整個(gè)NT領(lǐng)域。幾乎每一個(gè)管理任務(wù)最終都會(huì) 去改變系統(tǒng)目錄中的某一個(gè)目錄。象加入新用戶到組里面,新建一個(gè) 互聯(lián)網(wǎng)網(wǎng)站,或則更新電子郵件目錄等等。注意的是,Windows2000 的活動(dòng)目錄已經(jīng)支持這個(gè)技術(shù)。 微軟已經(jīng)提供了一些功能很強(qiáng)大的COM接口來(lái)訪問(wèn)不同的目錄服務(wù)。 ADS 命名空間和provider ADS provider的概念和ODBC結(jié)構(gòu)很相象,例如Oracle的ODBC驅(qū)動(dòng)器讓一臺(tái)機(jī)器連接到 Oracle的數(shù)據(jù)庫(kù)中,但是這并不意味著這個(gè)數(shù)據(jù)庫(kù)確實(shí)存在。 同樣的關(guān)系也使用與ADSI,它是一個(gè)適用與不同的目錄命名空間的公共接口。 也許這個(gè)目錄命名空間存在與網(wǎng)絡(luò)中。 在一個(gè)典型的服務(wù)器上,當(dāng)安裝了正確的工具箱后,你會(huì)找到三個(gè)ADS provider 他們是: WinNT: - 給NT及其網(wǎng)絡(luò)用的 IIS: - 給IIS用的 LDAP: - 給MS Exchange和Windows200的活動(dòng)目錄用的 也許你還會(huì)發(fā)現(xiàn)下面的provider NWCOMPAT: - 給Novell 3.1用的 NDS: - 給Novell Directory Services用的 每一個(gè)命名空間對(duì)象都由目錄服務(wù)的根節(jié)點(diǎn)集組成,典型的例子是 NT的domain或者server,但不是所有的provider都能夠自動(dòng)發(fā)現(xiàn)根目錄節(jié)點(diǎn)。 你能夠綁定到一個(gè)WinNT:對(duì)象上它會(huì)提供一個(gè)NT域列表 但是對(duì)于IIS和LDAP的命名空間對(duì)象,則既沒有IIS也沒有MS Exchange的根節(jié)點(diǎn). 在使用的時(shí)候而必須要被指明。
容器,會(huì)員,集合 對(duì)于大部分而言,目錄是一個(gè)分層目錄結(jié)構(gòu)的對(duì)象同時(shí)它還包容了其他的對(duì)象 舉例來(lái)說(shuō),一個(gè)物理的IIS服務(wù)器有多個(gè)網(wǎng)站,每個(gè)網(wǎng)站還可以有多個(gè)目錄( 或則網(wǎng)站的運(yùn)用程序),而這些目錄還有子目錄。 一個(gè)NT的domain能夠有多個(gè)服務(wù)器等等。
在ADSI術(shù)語(yǔ)中,所有上面的容器對(duì)象又包容其它對(duì)象,就組成了命名空間樹。 典型的代碼如下: Set oAds = GetObject("WinNT://MyDomain")
For Each oAdsChild in oAds
' do something
Next
分層目錄模型并不能夠完全描述對(duì)象之間的關(guān)系。個(gè)別而言,NT的用戶和組對(duì)象 約束與Domain 和 Server對(duì)象,但是他們之間又有一個(gè)附加的會(huì)員關(guān)系。 ADSI對(duì)象模型通過(guò).Groups和.Menmbers屬性來(lái)表示會(huì)員關(guān)系 例如一個(gè)典型的列表如下: Set oAds = GetObject("WinNT://MyDomain/Administrator") For Each oAdsGroup in oAds.Groups ' do something Next ' ... Set oAds = GetObject("WinNT://MyDomain/Domain Users") For Each oAdsMember in oAds.Members ' do something Next 仔細(xì)觀察上面的代碼的微妙的不同之處 對(duì)一個(gè)對(duì)象本身執(zhí)行列表,將返回它的子層。 對(duì)一個(gè)對(duì)象的.Member屬性執(zhí)行列表將返回它的會(huì)員列表。 最后,還有一些動(dòng)態(tài)集合來(lái)表示那些暫時(shí)獨(dú)立的對(duì)象。 一個(gè)典型的例子是在打印隊(duì)列中的任務(wù).PrintJobs集合
Schema對(duì)象 每個(gè)ADS對(duì)象都聯(lián)系在一個(gè)SCHEMA對(duì)象,來(lái)表示它的性能和特征 我們?cè)趯懘a的時(shí)候經(jīng)常碰到這樣的問(wèn)題:我的對(duì)象到底支持那些屬性 這是一個(gè)容器對(duì)象,或則對(duì)象有可能包含什么樣的類型。 例如,在原則上,一個(gè)目錄服務(wù)本身就是一個(gè)徹底的SCHEMA對(duì)象。
準(zhǔn)備運(yùn)行程序 這個(gè)ADS瀏覽程序需要有一定的安全權(quán)限才能夠運(yùn)行。 拷貝這個(gè)ADS瀏覽文件到你的網(wǎng)絡(luò)中的一個(gè)共享的目錄中 映射一個(gè)虛擬的web目錄 指派這個(gè)目錄有管理者的權(quán)限。
看一看命名空間樹
在這里使用了微軟的HtmlHelp Java applet. 它能夠產(chǎn)生我們需要的樹狀結(jié)構(gòu)。尤為重要的是它能夠提供對(duì)子樹的支持 因?yàn)槲也⒉辉敢饽梦业恼麄(gè)目錄樹來(lái)冒險(xiǎn)。 一個(gè)有關(guān)HtmlHelp applet的討論會(huì)遠(yuǎn)遠(yuǎn)超出現(xiàn)在的話題,下面就只給出很簡(jiǎn)短的版本: <UL> <!-- ... --> <LI>IIsWebServer Objects <UL> <LI> 1 <!-- on click: 顯示頁(yè)面 AdsProperties.asp?AdsPath=IIS://myserver/W3SVC/1} --> <UL> <!-- on expand: 顯示下一級(jí) AdsTreeHhc.asp?AdsPath=IIS://myserver/W3SVC/1 --> </UL> <LI> 2 <!-- on click: 顯示頁(yè)面 AdsProperties.asp?AdsPath=IIS://myserver/W3SVC/2} --> <UL> <!-- on expand: 顯示下一級(jí) AdsTreeHhc.asp?AdsPath=IIS://myserver/W3SVC/2 --> </UL> <!-- ... --> </UL> <!-- ... --> </UL>
怎么找到目錄樹的節(jié)點(diǎn) 程序流程應(yīng)該如下: 1。綁定到一個(gè)目錄對(duì)象 2。查找與之關(guān)聯(lián)的schema類 3。如果它是一個(gè)容器對(duì)象,那么 For all 可能的容器 in 這個(gè)對(duì)象 (通過(guò)schema得到) 對(duì)所有的對(duì)象進(jìn)行實(shí)現(xiàn) 使用HtmlHelp applet生成<LI>... 在實(shí)現(xiàn)過(guò)程中,其實(shí)一共才10行代碼,但是每一行代碼都有起自己的難點(diǎn) 掌握了它們你就能夠?qū)崿F(xiàn)很多其它美妙的功能。
難點(diǎn)一:查找Schema類對(duì)象 第一個(gè)難點(diǎn)就是并不是所有的ADS對(duì)象都有真正有一個(gè)schema. 一段程序段如下 Set oAds = GetObject(vAdsPath) Set oAdsClass = GetObject(oAds.Schema) 對(duì)于一些高一級(jí)的對(duì)象來(lái)說(shuō)這段代碼將會(huì)失敗.必須再加一點(diǎn)異常處理。 Function GetClass(oADs) On Error Resume Next Set GetClass = Nothing Set GetClass = GetObject(oADs.Schema) End Function Set oAdsClass = GetClass(oAds) If Typename(oAdsClass) <> "Nothing" Then ' do something End If
通過(guò)管理一個(gè)schema類,我們查看它的.Container屬性來(lái)決定我們處理的容器類型。 接著當(dāng)我們使用它的.Containment數(shù)組來(lái)得到對(duì)象的類。 舉例來(lái)說(shuō),一些Domain對(duì)象將返回一個(gè)schema類數(shù)組,其中包含有 字符串"Computer", "User", "Group", 和 "Schema". 理論上的代碼如下 If oAdsClass.Container Then vContainment = oAdsClass.Containment For vIdx=0 to uBound(vContainment) oAds.Filter = Array(vContainment(vIdx)) For Each oAdsChild in oAds ' write an <LI>... entry Next Next End If 但是又出現(xiàn)問(wèn)題了,這個(gè)方法有時(shí)候不能夠工作。一個(gè)WinNT Domain的.Containment數(shù)組 僅僅返回本來(lái)是4個(gè)對(duì)象類中的3個(gè).而LDAP的provider根本就不執(zhí)行.Container和.Containment屬性 這樣我們就沒法再使用上面的代碼了,只好針對(duì)這些怪異的現(xiàn)象造出一些怪異的代碼了 其它奇怪的地方 下面是一些很怪異的代碼,例如NT的LanmanServer對(duì)象可以想象它應(yīng)該有一個(gè)FileService 類 并且包含有一個(gè)FileShare類對(duì)象.正確的代碼如下: Set oAds = GetObject("WinNT://MyDomain/MyServer/LanmanServer") 但是很不幸的是當(dāng)我們調(diào)用它的父節(jié)點(diǎn)時(shí)將會(huì)出錯(cuò) Set oAds = GetObject("WinNT://MyDomain/MyServer") oAds.Filter = Array("FileService") For Each oAdsChild in oAds ' 這里的代碼將永遠(yuǎn)不會(huì)執(zhí)行 Next 下面類似的辦法也會(huì)出錯(cuò): Set oAds = GetObject("WinNT://MyDomain/MyServer") For Each oAdsChild in oAds If oAdsChild.Name = "LanmanServer" Then For Each oAdsGrandChild in oAdsChild ' 出錯(cuò) Next End If Next 這是為什么呢,其實(shí)LanmanServer有一個(gè)雙重身份.它是一個(gè)FileService對(duì)象 但同時(shí)它也是一個(gè)普通的Service對(duì)象。所以下面這段怪異的代碼就產(chǎn)生了: For Each oAdsChild in oAds If oAdsChild.Name = "LanmanServer" Then Set oAdsChild = GetObject(oAdsChild.AdsPath) For Each oAdsGrandChild in oAdsChild ' 終于成功了 Next End If Next
對(duì)象性質(zhì): 同上面相比,對(duì)象的屬性相對(duì)容易獲得。每個(gè)對(duì)象可以想象得到都有一個(gè)核心的屬性。 比如name,通過(guò)這個(gè)相同的屬性能夠很容易的使用對(duì)象: vAdsName = oAds.Name 大多數(shù)對(duì)象還有這樣的屬性.MandatoryProperties 和 .OptionalProperties , 這都能夠通過(guò)他們 的schema類得到,它們的數(shù)值可以通過(guò)對(duì)象的.GetEx方法得到: For Each vProp in oAdsClass.MandatoryProperties vPropValue = oAds.GetEx(vProp) Next
|
溫馨提示:喜歡本站的話,請(qǐng)收藏一下本站!