|
網(wǎng)絡(luò)技術(shù)是從1990年代中期發(fā)展起來(lái)的新技術(shù),它把互聯(lián)網(wǎng)上分散的資源融為有機(jī)整體,實(shí)現(xiàn)資源的全面共享和有機(jī)協(xié)作,使人們能夠透明地使用資源的整體能力并按需獲取信息。資源包括高性能計(jì)算機(jī)、存儲(chǔ)資源、數(shù)據(jù)資源、信息資源、知識(shí)資源、專(zhuān)家資源、大型數(shù)據(jù)庫(kù)、網(wǎng)絡(luò)、傳感器等。 當(dāng)前的互聯(lián)網(wǎng)只限于信息共享,網(wǎng)絡(luò)則被認(rèn)為是互聯(lián)網(wǎng)發(fā)展的第三階段。 前面介紹堆棧幀時(shí)曾經(jīng)提到過(guò),對(duì)所有跨越 Assembly/AppDomain 的調(diào)用,都會(huì)有特殊的幀被放入堆棧中做標(biāo)記。因此在調(diào)用鏈跨越兩個(gè) Assembly/AppDomain 時(shí),堆棧遍歷回調(diào)函數(shù)將有一個(gè)合適的時(shí)機(jī),檢測(cè)新的 Assembly/AppDomain 是否擁有足夠權(quán)限。這兩類(lèi)檢測(cè)思路類(lèi)似,都是先通過(guò) Assembly::GetSecurityDescriptor 函數(shù) (Assembly.cpp:747) 或 AppDomain::GetSecurityDescriptor 函數(shù) (AppDomain.cpp:1146) 獲取一個(gè)安全描述符 SecurityDescriptor;然后對(duì)需要進(jìn)行 CAS 檢測(cè)的情況,調(diào)用 SecurityDescriptor::GetGrantedPermissionSet 函數(shù) (Security.cpp:2218) 獲得相關(guān)權(quán)限集;最后調(diào)用回調(diào)函數(shù)傳入?yún)?shù)中的 pfnCheckGrants 函數(shù)指針,進(jìn)行權(quán)限驗(yàn)證。 值得注意的是,當(dāng)安全描述符被標(biāo)記為完全可信任 (SecurityDescriptor::IsFullyTrusted())、堆棧遍歷參數(shù)指定非受限模式 (IUnrestrictedPermission)、以及 Assembly 是系統(tǒng) BCL 類(lèi)庫(kù)(mscorlib.dll) 或 AppDomain 是缺省 AppDomain (用于加載 BCL 類(lèi)庫(kù),具體說(shuō)明參見(jiàn)《用WinDbg探索CLR世界 [6] AppDomain 的創(chuàng)建過(guò)程 》一文),則忽略 CAS 檢測(cè)。 對(duì)完全可信任概念的含義,可以參考《可怕的 Fully Trusted Code》一文。 如果需要進(jìn)行 CAS 檢測(cè),則 CheckGrants 函數(shù) (ComCodeAccessSecurityEngine.cpp:128) 將完成權(quán)限的驗(yàn)證工作。而其實(shí)際工作,則將通過(guò) Managed 方法 CodeAccessSecurityEngine::CheckHelper 方法 (CodeAccessSecurityEngine.cs:230) 完成。而 CheckHelper 方法將通過(guò)權(quán)限類(lèi)型本身的 IsSubsetOf/Intersect 等方法的實(shí)現(xiàn),來(lái)判斷 Assembly/AppDomain 現(xiàn)有權(quán)限集,是否包括請(qǐng)求的權(quán)限。而 Assembly/AppDomain 現(xiàn)有權(quán)限集,則是在 Assembly 被載入以及 AppDomain 被創(chuàng)建時(shí),由 CLR Loader 創(chuàng)建的。以后有機(jī)會(huì)再專(zhuān)門(mén)寫(xiě)篇文章分析這個(gè)權(quán)限集的構(gòu)建邏輯。 以下內(nèi)容為程序代碼: private static void CheckHelper(PermissionSet grantedSet, PermissionSet deniedSet, CodeAccessPermission demand, PermissionToken permToken) { if (permToken == null) permToken = PermissionToken.GetToken(demand); try { // 獲取權(quán)限集不能為空 if (grantedSet == null) { throw new SecurityException(...); } // 不處理權(quán)限集不受限或請(qǐng)求權(quán)限為非受限權(quán)限的情況 else if (!grantedSet.IsUnrestricted() || !(demand is IUnrestrictedPermission)) { CodeAccessPermission grantedPerm = (CodeAccessPermission)grantedSet.GetPermission(permToken); if (grantedPerm == null) { if (!demand.IsSubsetOf( null )) throw new SecurityException(String.Format(...); else return; } } // 驗(yàn)證權(quán)限沒(méi)有被顯式禁止 if (deniedSet != null) { CodeAccessPermission deniedPerm = (CodeAccessPermission)deniedSet.GetPermission(permToken); if (deniedPerm != null) { if (deniedPerm.Intersect(demand) != null) { throw new SecurityException(...); } } } } catch (Exception e) { // 所有的非 SecurityException 異常將都被轉(zhuǎn)換為 SecurityException 異常 // 因?yàn)檫@些異常的發(fā)生都是因?yàn)楂@取指定權(quán)限操作失敗的原因 if (e is SecurityException) throw e; else throw new SecurityException(...); } } 最后 CodeAccessCheckStackWalkCB 還需要處理顯式指定了安全對(duì)象幀的情況。對(duì)幀安全對(duì)象進(jìn)行檢測(cè)的 CheckFrameData 方法 (ComCodeAccessSecurityEngine.cpp:231) 與 CheckGrants 類(lèi)似,也是最終通過(guò) CheckHelper 方法實(shí)現(xiàn)的,這里就不羅嗦了。堆棧幀的安全對(duì)象,等到介紹堆棧結(jié)構(gòu)的時(shí)候再詳細(xì)解釋。 至此,CLR 中代碼訪(fǎng)問(wèn)安全檢測(cè)的大致實(shí)現(xiàn)思路以及比較清晰了,等把堆棧幀結(jié)構(gòu)和 CLR Loader 安全權(quán)限集構(gòu)建的文章弄完,再整理篇完整的,呵呵。 網(wǎng)絡(luò)的神奇作用吸引著越來(lái)越多的用戶(hù)加入其中,正因如此,網(wǎng)絡(luò)的承受能力也面臨著越來(lái)越嚴(yán)峻的考驗(yàn)―從硬件上、軟件上、所用標(biāo)準(zhǔn)上......,各項(xiàng)技術(shù)都需要適時(shí)應(yīng)勢(shì),對(duì)應(yīng)發(fā)展,這正是網(wǎng)絡(luò)迅速走向進(jìn)步的催化劑。 |
溫馨提示:喜歡本站的話(huà),請(qǐng)收藏一下本站!