| 本單元內容 | |
| 目標 | |
| 適用於 | |
| 如何使用本單元 | |
| 概觀 | |
| 資源存取 | |
| 完全信任與部分信任 | |
| 在 ASP.NET 裡設定程式碼存取安全性 | |
| ASP.NET 原則檔 | |
| ASP.NET 原則 | |
| 開發部分信任 Web 應用程式 | |
| 信任等級 | |
| 部分信任 Web 應用程式的方法 | |
| 自訂原則 | |
| 沙箱特殊權限程式碼 | |
| 決定要採取何種方法 | |
| 中度信任 | |
| 中度信任限制 | |
| 總結 | |
| 其他資源 |
程式碼存取安全性是一種資源限制模型,可以讓系統管理員判斷特定的程式碼是否能存取指定的資源及執行其他特殊權限操作,以及如何存取及執行。本單元著重在 ASP.NET 程式碼存取安全性原則設定,並且會示範如何克服開發部分信任 Web 應用程式時可能遇到的一些障礙。
單元中會詳細解說程式碼存取安全性的實用元素,而且您還會學到如何開發因程式碼存取安全性提供之安全性保護而受惠的中度信任 Web 應用程式,這些應用程式還是能夠使用要求完全信任的元件。
本單元還包含如何建立自訂 ASP.NET 信任原則的資訊,並包括兩份很有用的清單:
| • | 套用了 APTCA (AllowPartiallyTrustedCallersAttribute) 的系統組件。 |
| • | 預設 ASP.NET 原則權限與信任等級。這指定每個 ASP.NET 信任等級建立了什麼樣的主要限制。 |
透過本單元即可:
| • | 瞭解 ASP.NET 原則檔案如何作用,以及如何建立自訂原則。 |
| • | 開發部分信任 Web 應用程式。 |
| • | 使用部分信任 Web 應用程式的 OLE DB、事件日誌、Web 服務及登錄。 |
| • | 沙箱 (Sandbox) 管理特殊權限程式碼。 |
| • | 知道何時使用沙箱管理,何時自訂現有的 ASP.NET 信任原則。 |
本單元適用於下列產品及技術:
| • | Microsoft® Windows® 2000 Server 及 Microsoft Windows Server 2003 |
| • | Microsoft .NET Framework 1.1 及 ASP.NET 1.1 |
本單元並不包含程式碼存取安全性的基礎。文中假設讀者已具備必要知識,不過也會適當地重述重要概念。如需存取程式碼存取安全性如何運作的詳細資訊,請參閱單元 8<程式碼存取安全性實務>。
使用本單元認識如何使用程式碼存取安全性鎖定您的 Web 應用程式,以及加強伺服器對潛在威脅的防護。
如果您管理的是網際網路提供者 (ISP) 的共用主機環境或工作,在同一部 Web 伺服器器上執行不同公司的多套應用程式,可以使用程式碼存取安全性來:
| • | 將各應用程式互相隔離。
|
| • | 將應用程式與系統資源隔離。
|
另外請注意,Windows Server 2003 與 Internet Information Services (IIS) 6.0 提供更多的 Web 應用程式處理序隔離。處理序隔離配合程式碼存取安全性,是應用程式隔離的建議模型。
如需詳細資訊,請參閱單元 20<裝載多個 ASP.NET 應用程式>。
傳統的主體式安全性,例如作業系統所提供的,會根據使用者識別身份授權對資源的存取。
使用 Microsoft .NET Framework 1.1 版,系統管理員可以設定可能包含多個組件之 ASP.NET Web 應用程式與 Web 服務的原則。也可以授與程式碼存取安全性權限,讓應用程式能夠存取特定的資源類型,以及執行特定的特殊權限操作。
例如:
| • | 系統管理員可能會決定從網際網路下載的程式碼不應授與存取任何資源的權限,而由特定公司開發的 Web 應用程式碼則應給予較高的信任,以及允許其存取檔案系統、事件日誌及 Microsoft SQL Server 資料庫。 |
| • | 由本機系統管理員啟動的程式在本機電腦上沒有限制。但是,如果系統管理員的識別身份被欺騙,惡意使用者可以使用系統管理員的安全性等級執行程式碼,惡意使用者也沒有限制。 |
這些都是程式碼存取安全性很重要的區域,因為它可以根據程式碼本身提供其他限制和安全性,而非根據執行程式碼的使用者來提供。
注意 使用 .NET Framework 1.0 版建立的 Web 應用程式和 Web 服務一律以不受限制的程式碼存取權限執行。這無法設定。
ASP.NET 應用程式和 Managed 程式碼中所有資源存取一般都受到下列兩個安全保護層的保護:
| • | 程式碼存取安全性。這個安全保護層會確認目前呼叫堆疊中,資源存取程式碼之前和本身的所有程式碼都得到存取資源的授權。系統管理員使用程式碼存取安全性原則將權限授與組件。權限準確地決定組件可以存取哪些資源類型。許多權限類型對應到可以存取的不同資源類型。這些類型包括檔案系統、登錄、事件日誌、目錄服務、Microsoft SQL Server、OLE DB 資料來源及網路資源。
|
| • | 作業系統/平台安全性:這個安全保護層會確認要求之執行緒的安全性等級可以存取資源。如果執行緒是模擬的,則會使用執行緒模擬權杖。否則,會使用處理序權杖,並以其和連接至資源的存取控制清單 (ACL) 比較,以決定是否能夠執行要求的操作,以及可以存取的資源。 |
這兩項檢查都必須成功,才能夠順利存取資源。.NET Framework 類別所公開的所有資源類型都有程式碼存取權限的保護。[圖 9.1] 顯示 Web 應用程式所存取的一些一般資源類型,以及要成功存取所需的相關程式碼存取權限。

[圖 9.1]
從 ASP.NET Web 應用程式存取的一般資源類型和相關的權限類型
在預設的狀況下,Web 應用程式是以完全信任執行。程式碼存取安全性原則會授與完全信任的應用程式不受限制的程式碼存取權限。這些權限包含內建的系統與自訂權限。也就是說,程式碼存取安全性不會防止您的應用程式存取 [圖 9.1] 中所示的任何安全資源類型。資源存取的成功或失敗完全由作業系統層級安全性決定。以完全信任執行的 Web 應用程式包括使用 .NET Framework 1.0 版建立的所有 ASP.NET 應用程式。在預設的狀況下,.NET Framework 1.1 版應用程式是以完全信任執行,但是可以使用 <trust> 元素設定信任等級,這會在本單元後面說明。
如果應用程式是以「完全」以外的信任等級設定,就稱為部分信任應用程式。部分信任應用程式的權限有所限制,會限制其存取安全資源的能力。
重要 在 .NET Framework 1.0 版上建立的 Web 應用程式一律會以完全信任執行,因為 System.Web 裡的類型會要求完全信任呼叫者。
在預設的狀況下,Web 應用程式是以完全信任執行,具有不受限制的權限。若要在 ASP.NET 裡修改程式碼存取安全性信任等級,您必須在 Machine.config 或 Web.config 裡設定一個參數,並且將應用程式設定為部分信任應用程式。
Machine.config 裡的 <trust> 元素控制了是否針對 Web 應用程式啟用程式碼存取安全性。開啟 Machine.config,搜尋「<trust>」,您會看到下列內容:
<system.web> <!-- level="[Full|High|Medium|Low|Minimal]" --> <trust level="Full" originUrl=""/> </system.web>
將信任等級設定為「Full」,會有效地停用程式碼存取安全性,因為權限要求不會妨礙資源存取。這是在 .NET Framework 1.0 版上建立之 ASP.NET Web 應用程式的唯一選項。清單中從「Full」到「Minimal」,每個等級都會除掉更多的權限,更加限制您的應用程式存取安全資源及執行特殊權限操作的能力。每個等級都提供更大程度的應用程式隔離。[表 9.1] 顯示預先定義的信任等級,並指出和前一等級相比的主要限制。
[表 9.1] ASP.NET 信任等級施加的限制
| ASP.NET 信任等級 | 主要限制 |
完全 | 無限制的權限。應用程式可以存取受作業系統安全性控制的任何資源。支援所有的特殊權限操作。 |
高 | 無法呼叫 Unmanaged 程式碼 |
中 | 除了上述之外,檔案存取是限制在目前的應用程式目錄,而且不允許登錄存取。 |
低 | 除了上述之外,應用程式無法連接至 SQL Server,而且程式碼無法呼叫 CodeAccessPermission.Assert (沒有宣告安全性權限)。 |
最小 | 只能使用執行權限。 |
如果 Web 伺服器管理員想要使用程式碼存取安全性確保應用程式隔離,以及限制對系統層級資源的存取,系統管理員必須能夠在電腦層級定義安全性原則,並防止個別應用程式覆蓋它。
應用程式服務提供者或負責在同一部伺服器上執行多個 Web 應用程式的任何人,應該鎖定所有 Web 應用程式的信任等級。其方式是,將 Machine.config 裡的 <trust> 元素以 <location> 標記括住,並將 allowOverride 屬性設定為 false,如以下範例中所示。
<location allowOverride="false"> <system.web> <!-- level="[Full|High|Medium|Low|Minimal]" --> <trust level="Medium" originUrl=""/> </system.web> </location>
也可以在 <location> 元素上使用 path 屬性,將設定套用至不能覆蓋的特定網站或 Web 應用程式。如需 <location> 元素的詳細資訊,請參閱單元 19<保障 ASP.NET 應用程式及 Web 服務的安全>。
每個信任等級會對應至一個個別的 XML 原則檔,而原則檔會列出每個信任等級授與的權限集合。原則檔位於以下目錄:
%windir%\Microsoft.NET\Framework\{version}\CONFIG
Machine.config 中的 <trustLevel> 元素會將信任等級對應至原則檔,這個元素就在 <trust> 元素之上,如以下範例所示。
<location allowOverride="true"> <system.web> <securityPolicy> <trustLevel name="Full" policyFile="internal"/> <trustLevel name="High" policyFile="web_hightrust.config"/> <trustLevel name="Medium" policyFile="web_mediumtrust.config"/> <trustLevel name="Low" policyFile="web_lowtrust.config"/> <trustLevel name="Minimal" policyFile="web_minimaltrust.config"/> </securityPolicy> <!-- level="[Full|High|Medium|Low|Minimal]" --> <trust level="Full" originUrl=""/> </system.web> </location>
注意 完全信任等級沒有原則檔。這是一個特殊情況,只表示不受限制的所有權限集合。
ASP.NET 原則可以完全設定。除了預設的原則層級之外,系統管理員可以建立自訂的權限檔,並使用本單元後面說明的 <trust> 元素設定。與自訂層級相關的原則檔也必須以 Machine.config 中的 <trustLevel> 元素定義。
程式碼存取安全性原則為階層性,並且在多個層級管理。可以為企業、電腦、使用者應用程式領域層級建立原則。ASP.NET 程式碼存取安全性原則就是應用程式領域層級原則的例子。
分開的 XML 設定檔中的設定定義了每個層級的原則。企業、電腦及使用者原則可以使用 Microsoft .NET Framework 設定工具設定,但是 ASP.NET 原則檔必須使用 XML 或文字編輯器手動編輯。
個別 ASP.NET 信任等級原則檔會表明,會授與在特定信任等級設定的應用程式哪些權限。授與 ASP.NET 應用程式的 actual 權限是將所有 原則層級的權限授與交集來決定,包括企業、電腦、使用者及 ASP.NET (應用程式領域) 層級原則。
因為原則是從企業層級下向評估到 ASP.NET 應用程式層級,所以權限只能一層層拿掉。如果較高的層級沒有先授與權限,則不能在 ASP.NET 層級加入權限。這個方法可確保企業管理員永遠有最終決定權,而且在應用程式領域內執行的惡意程式碼不能要求及得到授與比管理員所設定的更多的權限。
如需原則評估的詳細資訊,請參閱單元 8<程式碼存取安全性實務>。
若要查看特定的信任等級定義了哪些權限,請在記事本或 (最好是) XML 編輯器內開啟相關的原則檔,並找出「ASP.NET」指名的權限集合。這個權限集合會列出在目前信任等級針對應用程式設定的權限。
注意 您還會看到「FullTrust」和「Nothing」權限組合。這些集合並未包含權限元素,因為「FullTrust」必然包含所有權限,而「Nothing」則不包含任何權限。
以下程式碼片段顯示 ASP.NET 原則檔的主要元素:
<configuration> <mscorlib> <security> <policy> <PolicyLevel version="1"> <SecurityClasses> ... 安全性類別、權限類型及 程式碼群組類型的清單 ... </SecurityClasses> <NamedPermissionSets> <PermissionSet Name="FullTrust" ... /> <PermissionSet Name="Nothing" .../> <PermissionSet Name="ASP.NET" ... ... 這是要注意的部分 ... ... 個別權限的清單 ... <IPermission class="AspNetHostingPermission" version="1" Level="High" /> <IPermission class="DnsPermission" version="1" Unrestricted="true" /> ...繼續的權限清單... </PermissionSet> </PolicyLevel version="1"> </policy> </security> </mscorlib> </configuration>
請注意,每個權限是由一個 <IPermission> 元素定義,定義了權限類型名稱、版本及是否為無限制狀態。
許多權限都包含狀態,用於調整權限指定的存取權利。狀態準確地決定權限允許您的應用程式做些什麼。例如,FileIOPermission 可能會指定目錄和存取類型 (讀取、寫入等)。以下權限要求會要求授與呼叫程式碼讀取權限,以存取 C:\SomeDir 目錄:
(new FileIOPermission(FileIOPermissionAccess.Read, @"C:\SomeDir")).Demand();
FileIOPermission 在無限制狀態下,允許任何類型存取檔案系統上的任何區域 (當然,作業系統安全性仍然適用)。以下權限要求會要求授與呼叫程式碼無限制的 FileIOPermission:
(new FileIOPermission(PermissionState.Unrestricted)).Demand();
ASP.NET 原則檔包含一個「ASP.NET」具名權限集合。這定義了應用程式領域原則授與相關應用程式的權限集合。
ASP.NET 原則也推出一個自訂的 AspNetHostingPermission,它有一個相關的 Level 屬性,對應至預設的層級之一。System.Web 與 System.Web.Mobile 中所有的公開類型都以這個權限的最小 (Minimum) 層級需求來保護。這種風險降低策略的設計,是要確保若系統管理員沒有設定特定的原則,Web 應用程式碼就無法在其他的部分信任環境中使用。
如果您編輯 ASP.NET 原則檔之一,會注意到某些權限元素包含替代參數 ($AppDirUrl$、$CodeGen$ 和 $Gac$)。這些參數可以讓您設定屬於 Web 應用程式一部分,但卻是從不同位置載入之組件的權限。在第一次載入 Web 應用程式組件時會評估安全性原則,這時每個替代參數都會以一個實際值取代。您的 Web 應用程式可能包含下列三種組件類型:
| • | 在建立時編譯,並部署在應用程式 Bin 目錄下的私密組件 重要 這一類組件無法使用增強名稱。ASP.NET Web 應用程式使用的增強名稱組件必須安裝在全域組件快取中。因為多重應用程式領域工作處理序的內部工作之故,這是必要的限制。 |
| • | 回應網頁要求所產生的動態編譯組件 |
| • | 從電腦全域組件快取載入的共用組件 |
這每一種類型都有相關聯的替代參數,[表 9.2] 總結了這些參數。
[表 9.2] ASP.NET 程式碼存取安全性原則替代參數
| 參數 | 代表 |
$AppDirUrl$ | 應用程式的虛擬根目錄。這允許將權限套用至應用程式之 Bin 目錄內的程式。例如,虛擬目錄若是對應至 C:\YourWebApp,則 $AppDirUrl$ 等於 C:\YourWebApp。 |
$CodeGen$ | 包含動態產生之組件 (例如,.aspx 網頁編譯的結果) 的目錄。這可以針對每個應用程式設定,並且預設為 |
$Gac$ | 安裝在電腦全域組件快取 (GAC) (%windir%\assembly) 中的任何組件。這允許將權限套用至 Web 應用程式從 GAC 載入的增強名稱組件。 |
部分信任 Web 應用程式是沒有完全信任,擁有由程式碼存取安全性原則決定之限制程式碼存取權限集合的應用程式。因此,部分信任應用程式存取安全資源和執行其他特殊權限操作的能力有所限制。部分信任應用程式的某些權限會被拒絕,因此無法直接存取需要這些權限的資源。其他權限則以有限制的方法授與,因此可以存取需要這些權限的資源,但是有所限制。例如,限制的 FileIOPermission 可能指定應用程式可以存取檔案系統,但是只能存取應用程式虛擬根目錄底下的目錄。
設定部分信任的 Web 應用程式或 Web 服務,可以限制應用程式存取重要系統資源或屬於其他 Web 應用程式之資源的能力。只授與應用程式需要的權限,可以建立最小權限的 Web 應用程式,萬一 Web 應用程式受到程式碼注入攻擊,還可以限制潛在的危害。
如果您拿現有的 Web 應用程式,重新設定它在部分信任等級執行,除非將應用程式嚴格限制在它所存取的資源,否則很可能會遇到下列問題:
| • | 您的應用程式無法呼叫未以 AllowPartiallyTrustedCallersAttribute (APTCA) 註釋的增強名稱組件。沒有 APTCA,增強名稱組件會發出完全信任的要求,在要求傳入您的部分信任 Web 應用程式時將會失敗。許多系統組件只支援完全信任呼叫者。以下清單顯示哪些 .NET Framework 組件支援部分信任呼叫者,部分信任 Web 應用程式可以直接呼叫它,不需要沙箱包裝函式組件。 注意 沙箱會在本單元後面詳細討論。 下列系統組件都套用了 APTCA,也就是,可以由部分信任 Web 應用程式或任何部分信任程式碼所呼叫:
如果您的部分信任應用程式因為呼叫沒有標示 APTCA 之增強名稱組件而失敗,會產生一般 SecurityException。在這種情況下,例外中並不會包含其他資訊來表示呼叫是因為對完全信任的要求失敗而失敗。 | ||||||||||||||||||||||
| • | 權限要求可能開始失敗。設定的信任等級可能不會授與必要的權限,讓您的應用程式存取特定的資源類型。以下是可以證明這有問題的一些常見案例:
|
如果您打算將現有的應用程式移轉為部分信任等級,逐漸減少權限以便看到應用程式放棄的部分,是一個很好的方法。例如,先將信任 level 屬性設定為高 (High),再設定為中 (Medium) 等。最後,應該使用的信任等級依要為應用程式加上的限制程度而定。使用下列各項作為指引:
| • | 設定為高、中、低或最小信任的應用程式將無法呼叫 Unmanaged 程式碼或服務元件、寫入事件日誌、存取 Message Queuing 佇列或存取 OLE DB 資料來源。 |
| • | 設定為高信任的應用程式有無限制的檔案系統存取權。 |
| • | 設定為中信任的應用程式有限制的檔案系統存取權。它們只能存取自己應用程式目錄階層中的檔案。 |
| • | 設定為低或最小信任的應用程式不能存取 SQL Server 資料庫。 |
| • | 最小信任應用程式不能存取任何資源。 |
[表 9.3] 辨別每一種 ASP.NET 信任等級授與的權限。表中省略了完全等級,因為它會毫無限制地授與所有權限。
[表 9.3] 預設的 ASP.NET 原則權限與信任等級
| 權限與狀態 | 高 | 中 | 低 | 最小 |
AspNetHosting | 高 | 中 | 低 | 最小 |
DnsPermission |
|
|
|
|
EnvironmentPermission |
| TEMP;TMP; |
|
|
EventLogPermission |
|
|
|
|
FileIOPermission |
|
|
|
|
IsolatedStorageFilePermission |
|
|
|
|
OleDbClientPermission |
|
|
|
|
PrintingPermission |
|
|
|
|
ReflectionPermission |
|
|
|
|
RegistryPermission |
|
|
|
|
SecurityPermission |
|
|
|
|
SocketPermission |
|
|
|
|
SqlClientPermission |
|
|
|
|
WebPermission |
| $OriginHost$ |
|
|
如果您開發部分信任應用程式,或啟用現有的應用程式在部分信任等級執行,而因為應用程式想要存取未授與相關權限的資源而遇到問題,則可以使用下列兩種基本方法:
| • | 自訂原則 |
| • | 沙箱管理特殊權限程式碼 |
正確的方法依問題何在而定。如果問題是因為您想要呼叫不包含 AllowPartiallyTrustedCallersAttribute 的系統組件兩造成的,這問題就變成如何授與程式碼完全信任。在此情況下,應該使用沙箱法,並授與沙箱包裝函式組件完全信任。
注意 自訂原則是兩種方法中較容易的,因為它不需要任何開發。
如果您的 Web 應用程式包含的程式碼需要的權限比特定 ASP.NET 信任等級授與的還要多,最簡單的方法是自訂原則檔,將額外的程式碼存取安全性權限授與您的 Web 應用程式。您可以修改現有的原則檔,授與額外的權限,或根據現有的原則檔建立新權限。
注意 如果您修改內建原則檔之一,例如,中度信任 Web_mediumtrust.config 原則檔,這會影響設定以中度信任執行的所有應用程式。
| • | 若要自訂特定應用程式的原則
|
不需要更新 ASP.NET 程式碼存取安全性原則的另一種方法,是將您的資源存取程式碼包含在其自己的包裝函式組件中,並設定電腦層級程式碼存取安全性原則,以授與特定組件適當的權限。然後您可以使用 CodeAccessPermission.Assert 方法沙箱較高特殊權限程式碼,這樣就不必變更 Web 應用程式的整體權限授與。Assert 方法可防止資源存取程式碼發出的安全性要求傳播回包裝函式組件界限之外的呼叫堆疊。
您可以將以下模式套用至需要存取限制資源或執行其他特殊權限操作的 (上層 Web 應用程式沒有足夠的權限的) 任何特殊權限程式碼:
1. | 將資源存取程式碼封裝在包裝函式組件中。
|
2. | 在存取資源之前宣告相關的權限。
宣告權限是很危險的,因為這表示呼叫您程式碼的程式碼可以存取您的組件所封裝的資源,不需要相關的資源存取權限。Assert 陳述式指出您的程式碼可以確認其呼叫者的合法。做法是,您的程式碼應要求其他權限,使其能在呼叫 Assert 之前授權呼叫程式碼。使用這種方式,只允許授與了其他權限的程式碼存取組件所公開的資源。 .NET Framework 可能不提供適當的要求權限。在這種情況下,可以建立及要求自訂的權限。如需如何建立自訂權限的詳細資訊,請參閱本指南<How To>一節中的<How To:建立自訂加密權限>。 |
3. | 以 APTCA 註釋包裝函式組件。
|
4. | 在 GAC 中安裝包裝函式組件。
<CodeGroup class="UnionCodeGroup" version="1" PermissionSetName="FullTrust> <IMembershipCondition class="UrlMembershipCondition" Url="$Gac$/*" version="1" /> </CodeGroup> 注意 預設的企業與本機電腦原則也會授與 [我的電腦] 區域中的任何程式碼 (包含安裝在 GAC 中的程式碼) 完全信任。這很重要,因為各個原則層級的授與權限會交集。 |
5. | 設定 Web 應用程式信任等級 (例如,將其設定為「Medium」)。 |
[圖 9.2] 顯示沙箱方法。

[圖 9.2]
將宣告相關權限的特殊權限程式碼沙箱隔離在其自己的組件內
使用另一個組件封裝資源存取及避免將資源存取程式碼放在 .aspx 檔案內或程式碼後置檔案內。例如,建立另一個資料存取組件以封裝資料庫存取。這樣較容易將應用程式移轉至部分信任環境。
正確的方法取決於您要解決的問題而定,以及您是否能夠修改 Web 伺服器上的安全性原則。
這是兩種方法中較容易的一種,不需要任何開發。但是,可能無法修改 Web 伺服器上的原則,而且在某些狀況下,呼叫 .NET Framework 類別庫的程式碼可能需要完全信任。在這些情況下,必須使用沙箱。例如,下列資源需要完全信任,而您的資源存取程式碼存取這些資源時,您必須將程式碼沙箱隔離:
| • | 事件日誌 (透過 EventLog 類別) |
| • | OLE DB 資料來源 (透過 ADO.NET OLE DB 資料提供者) |
| • | ODBC 資料來源 (透過 ADO.NET ODBC .NET 資料提供者) |
| • | Oracle 資料庫 (透過 ADO.NET Oracle .NET 資料提供者) |
注意 這份清單並不詳盡,但是包含目前需要完全信任的常用資源類型。
如果您將特殊權限應用程式沙箱隔離在另一個組件內,可以授與組件額外的權限。或者,可以只授與它完全信任,不要求整個應用程式以延伸的權限執行。
例如,請設想使用 ADO.NET OLE DB 資料提供者,並與 System.Data.OleDb.OleDbCommand 類別互動的程式碼。這個程式碼需要完全信任。雖然 System.Data.dll 組件以 AllowPartiallyTrustedCallersAttribute 標示,但是部分信任呼叫者無法呼叫 System.Data.OleDb.OleDbCommand 類別和其他類別,因為它受到完全信任的連結要求保護。若要檢視這個,請使用 %windir%\Microsoft.NET\Framework\{version} 目錄下的 permview 公用程式執行以下命令:
permview /DECL /OUTPUT System.Data.Perms.txt System.Data.dll
System.Data.Perms.txt 中的輸出包含下列輸出:
class System.Data.OleDb.OleDbCommand LinktimeDemand permission set: <PermissionSet class="System.Security.PermissionSet" version="1" Unrestricted="true"/>
這說明了保護 System.Data.OleDb.OleDbCommand 類別的連結要求中使用無限制的權限集合 (完全信任)。這類情況下,設定原則以授與您的部分信任程式碼特定無限制權限 (例如 OleDbPermission) 並不足夠。而是必須沙箱隔離您的資源存取程式碼並授與其完全信任,最簡單的方法就是將其安裝在 GAC 中。使用 Permview.exe 找出其他類別的權限需求,不過這只會顯示宣告式安全性屬性。如果類別命令地要求完全信任,無法透過 Permview.exe 看到這點。此時,可以從部分信任程式碼呼叫安全性需求及診斷任何安全性例外,以測試安全性需求。
注意 只因為組件標示 APTCA,並不表示所有包含的類別支援部分信任類別。某些類別可能包含完全信任的明確要求。
如果您裝載 Web 應用程式,可以選擇實作中度信任安全性原則,以限制特殊權限操作。本節著重在執行中度信任應用程式,並顯示如何克服可能遇到的問題。
以中度信任執行有下列兩個優點:
| • | 減少被攻擊的風險 |
| • | 應用程式隔離 |
由於中度信任並不授與應用程式所有權限的無限制存取,因此授與應用程式完全權限集合的子集可以減少您的被攻擊面。中度信任原則授與的許多權限也是在限制狀態。如果攻擊者因故能夠控制您的應用程式,所能做的事還是會受到限制。
使用程式碼存取安全性的應用程式隔離會限制對系統資源,以及其他應用程式擁有之資源的存取。例如,雖然可能允許處理序識別身份讀取及寫入 Web 應用程式目錄以外的檔案,但是中度信任應用程式的 FileIOPermission 是有限制的。它只允許應用程式讀取或寫入自己的應用程式目錄階層。
如果您的應用程式以中度信任執行,會遇到許多限制,其中最重要的有:
| • | 無法直接存取事件日誌。 |
| • | 檔案系統存取權有限制,只能存取應用程式之虛擬目錄階層中的檔案。 |
| • | 不能直接存取 OLE DB 資料來源 (雖然中度信任應用程式已授與 SqlClientPermission,允許存取 SQL Server)。 |
| • | 對 Web 服務的存取有限制。 |
| • | 不能直接存取 Windows 登錄。 |
本節會示範如何從中度信任 Web 應用程式或 Web 服務存取下列資源類型:
| • | OLE DB |
| • | 事件日誌 |
| • | Web 服務 |
| • | 登錄 |
中度信任 Web 應用程式不會授與 OleDbPermission。此外,OLE DB .NET 資料提供者目前要求完全信任呼叫者。如果您的應用程式以中度信任執行,而又需要存取 OLE DB 資料來源,請使用沙箱法。將資料存取程式碼放在另一個組件中,加上增強名稱,然後安裝在給予它完全信任的 GAC 中。
注意 除非將信任等級設定為「Full」,否則修改原則不會有作用,因為 OLE DB Managed 提供者要求完全信任。
[圖 9.3] 顯示其排列。

[圖 9.3]
沙箱 OLE DB 資源存取
使用這種方法時,您建立一個包裝函式組件,以封裝 OLE DB 資料來源存取。這個組件會得到授與完全信任權限,這是使用 ADO.NET OLE DB Managed 提供者的必要權限。
| • | 若要建立沙箱包裝函式組件以呼叫 OLE DB 資料來源
|
EventLogPermission 類別的設計,是要封裝程式碼存取事件日誌的權利。但是,目前必須授與程式碼完全信任,才能夠存取事件日誌。這表示中度信任 Web 應用程式不能直接存取事件日誌。若要執行此作業,必須沙箱 (Sandbox) 處理事件記錄程式碼。
首先,確定用於執行 Web 應用程式 (如果是模擬應用程式,則是執行緒識別身份) 的處理序帳戶能夠建立事件來源。處理序或執行緒識別身份必須能夠在以下機碼之下建立登錄機碼:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog
至少,任何模擬識別身份的 ASP.NET 處理序識別身份在此一登錄機碼上必須有下列權限:
| • | 查詢機碼值 |
| • | 設定機碼值 |
| • | 建立子機碼 |
| • | 列舉子機碼 |
| • | 通知 |
| • | 讀取 |
這些設定必須套用至上面所示的機碼和子機碼。或者,如果能夠使用系統管理員權限,則可以在安裝時建立事件來源。如需此一方法的詳細資訊,請參閱單元 10<建置安全的 ASP.NET 網頁和控制項>裡的「稽核和記錄」。
若要沙箱管理事件記錄程式碼,應建立一個包裝函式組件以封裝事件日誌存取權。然後將包裝函式組件安裝在全域組件快取中,使程式碼存取安全性原則能夠授與其完全信任。
| • | 若要建立沙箱包裝函式組件以寫入事件日誌
|
在預設的狀況下,中度信任原則會授與 ASP.NET Web 應用程式有限制的 WebPermission。若要能夠從您的 Web 應用程式呼叫 Web 服務,必須在您的應用程式的 <trust> 元素上設定 originUrl 屬性。
| • | 若要從中度信任 Web 應用程式呼叫單一 Web 服務
|
originUrl 值會用於 System.Text.RegEx 規則運算式類別的建構函式中,使其能在可由 Web 服務存取的 URL 執行合配。這個 RegEx 類別會配合 WebPermission 類別使用。「.*」會合配以「http://servername/」開頭的任何 URL。
評估 ASP.NET 時會使用 originUrl 屬性。它會提供 $OriginHost$ 替代參數的值。以下是 Web_mediumtrust.config 裡的 WebPermission 定義:
<IPermission class="WebPermission" version="1"> <ConnectAccess> <URI uri="$OriginHost$"/> </ConnectAccess> </Ipermission>
如果未指定由您的應用程式存取的 Web 伺服器,則任何 Web 服務都會因 SecurityException 而失敗。若要呼叫本機 Web 伺服器上的 Web 服務,請使用以下設定:
<trust level="Medium" originUrl="http://localhost/.*" />
如果您的應用程式必須存取不同伺服器上的多個 Web 服務,則您必須自訂 ASP.NET 原則,因為 Web.config 或 Machine.config 裡的 <trust> 元素只能指定一個 originUrl。
| • | 若要從中度信任應用程式呼叫多個 Web 服務
|
您可能需要呼叫使用 Windows 驗證的 Web 服務,並透過 Proxy 憑證快取指定驗證憑證。例如:
proxy.Credentials = System.Net.CredentialCache.DefaultCredentials;
在此情況下,ASP.NET 應用程式需要有能夠讀取 USERNAME 環境變數的 EnvironmentPermission。預設中度信任原則會將此權限授與 Web 應用程式。
在 ASP.NET 伺服器端的案例中,憑證是從 ASP.NET 應用程式的執行緒或處理序層級權杖取得。如果是從桌面應用程式使用 DefaultCredentials,會使用目前的互動使用者的權杖。EnvironmentPermission 的要求是一種風險緩和策略,它的設計是要確保程式碼無法任意使用本機使用者的憑證,以及將其公開到網路。
在預設的狀況下,中度信任 Web 應用程式不會授與 RegistryPermission。若要設定您的應用程式存取登錄,必須修改 ASP.NET 原則,將此權限授與您的應用程式,或開發具有必要權限的沙箱包裝函式組件。
沙箱法和前面在 OLE DB 資料來源和事件日誌所述的相同。
自訂原則的最簡單的方法是根據中度信任原則檔建立自訂原則檔,並設定您的應用程式使用自訂原則。自訂原則會將 RegistryPermission 授與應用程式。
| • | 若要建立自訂原則以允許登錄存取
|
程式碼存取安全性是一個資源限制安全性模型,可用於協助應用程式隔離。可以設定應用程式在各種部分信任等級執行。信任等級決定授與 ASP.NET Web 應用程式或 Web 服務的權限。這決定了可以存取的資源類型,以及可以執行的其他特殊權限操作類型。請注意,所有資源存取最終需遵守作業系統安全性。
建議的隔離模型使用 Windows Server 200 上的 IIS 6.0 應用程式集區,而且除了程式碼存取安全性之外,還提供處理序層級隔離。在 Windows 2000 上,只能使用程式碼存取安全性與另外的執行緒識別身份達成隔離。
移轉應用程式以部分信任執行通常需要某種程度的重新設計。如果應用程式存取部分信任等級不允許的資源,或呼叫不包含 APTCA 的增強名稱組件,您可能需要重新設計。在這些情況下,可以將特殊權限資源存取沙箱隔離在個別的包裝函式組件。某些情況中,可能可以建立及使用自訂原則檔,不過這要依賴您的 Web 伺服器的安全性原則而定。
將資源存取程式碼放在個別的組件中,避免將此程式碼放在 .aspx 檔案與程式碼後置檔案中,是一個很好的設計習慣。使用分開的組件可以讓程式碼存取安全性原則不受 Web 應用程式的影響,套用到組件,也允許您開發沙箱信任程式碼以執行資源存取。
有關其他詳細資訊,請參閱下列資源:
| • | MSDN Magazine 裡的《Security in .NET: The Security Infrastructure of the CLR Provides Evidence, Policy, Permissions, and Enforcement Services (英文)》,網址 http://msdn.microsoft.com/msdnmag/issues/02/09/SecurityinNET/default.aspx。 |
| • | MSDN Magazine 裡的《Security in .NET: Enforce Code Access Rights with the Common Language Runtime (英文)》,網址 http://msdn.microsoft.com/msdnmag/issues/01/02/CAS/default.aspx。 |
| • | LaMacchia、Lange、Lyons、Martin 及 Price 所著《.NET Framework Security (英文)》,Addison Wesley Professional 2002 年出版。 |
| • | "本指南<How To>一節中的<How To:建立自訂加密權限>。 |