淺談CLR 4.0安全模型的運作機制
CLR 4.0安全模型三層安全級別及其運作機制
CLR4.0中的安全級別,從低到高排列如下:
Transparent
SafeCritical
Critical
其運作機制如下圖所示,可以用三個箭頭加以說明:
Transparent的代碼可以調用SafeCritical的代碼
SafeCritical的代碼可以調用Critical的代碼
Transparent的代碼不可以調用Critical的代碼
下面的代碼展示了安全級別的運作機制:
1: using System;
2: using System.Security;
3:
4: // 這個屬性使得assembly中沒有Security標記的方法默認為Transparent方法
5: [assembly:AllowPartiallyTrustedCallers]
6:
7: namespace SecurityLevel
8: {
9: public class Program
10: {
11: // 標記Foo為Critical方法。
12: [SecurityCritical]
13: static void Foo()
14: {
15: Console.WriteLine("Hello Foo");
16: }
17:
18: static void Main()
19: {
20: // 這個調用會導致以下的異常:
21: // Unhandled Exception: System.MethodAccessException: SecurityLevel.Program.Foo()
22: // at SecurityLevel.Program.Main()
23: Foo();
24: }
25: }
26: }
Main函數由于沒有任何安全屬性,而且在assembly上有AllowPartiallyTrustedCallers屬性,所以他的安全級別是Transparent,根據前文提及的安全機制,不能直接調用Critical函數Foo,于是命令行上顯示了異常信息。
應用安全級別構筑體用程序
CLR 4.0安全模型提供了這樣的一個機制,用戶只有正確使用這些機制,才能構筑健壯的應用程序。在這里,“正確的使用”指的是合理的設置函數的安全級別,對三個安全級別設置的指導原則如下:
Critical:通常用來執行高危操作,比如對文件系統的讀寫。
SafeCritical:用來做安全方面的檢驗,或者只做限制性的操作。
Transparent:來自任何部分信任的程序代碼。
舉例來說,我們把三層模型應用到cookie的讀寫上,***層可以有一個Critical的函數,用來在文件系統上寫一個cookie文件。中間層有一個SafeCritical,用于檢驗cookie操作的文件是否屬于特定的文件夾,就好像做一個安全檢查:如果通過了,則允許操作;否則的話就拒絕之。
下面的例子展示了一個簡化后的應用,從D盤的temp文件夾中刪除文件。請參見代碼中的注釋理解程序。
1: using System;
2: using System.IO;
3: using System.Security;
4:
5: // 這個屬性使得assembly沒有Security標記的方法默認為Transparent方法
6: [assembly:AllowPartiallyTrustedCallers]
7:
8: namespace SecurityLevel
9: {
10: public class Program
11: {
12: /// <summary>
13: /// 該函數可以刪除文件系統上的任意函數。具有***的安全級別
14: /// </summary>
15: /// <param name="fileName">文件名</param>
16: [SecurityCritical]
17: static void DeleteFile(string fileName)
18: {
19: File.Delete(fileName);
20: }
21:
22: /// <summary>
23: /// 該函數驗證待刪文件是否在d:\temp中
24: /// </summary>
25: /// <param name="fileName">待刪文件名</param>
26: [SecuritySafeCritical]
27: static void DeleteFileFromTemp(string fileName)
28: {
29: if (fileName.StartsWith(@"d:\temp", StringComparison.CurrentCultureIgnoreCase)
30: {
31: DeleteFile(fileName);
32: }
33: else
34: {
35: throw new Exception("待刪文件不在temp文件夾中");
36: }
37: }
38:
39: static void Main()
40: {
41: // 該語句運行正常
42: DeleteFileFromTemp(@"d:\temp\a.txt");
43:
44: // 該語句拋出異常
45: DeleteFileFromTemp(@"d:\a.txt");
46: }
47: }
48: }
49:
安全級別和.NET類型系統
理解了安全級別的應用之后,我們來看看安全級別和.NET類型系統之間的關系:
安全級別和反射
反射機制提供了這樣三個屬性來探測一個類型(Type)和方法(MethodInfo)的安全級別
- IsSecurityCritical { get; }
- IsSecuritySafeCritical { get; }
- IsSecurityTransparent { get; }
大家可以觀察到,這三個屬性是只讀的,因為通常境況下,編譯器會寫入了相關信息。
CLR 4.0安全模型的安全級別和繼承
以下兩點值得注意:關于類型,子類型的安全級別必須等于或者高于父類型的安全級別;關于方法,繼承的方法不能改變基類型方法的安全級別
安全級別和委托(Delegate)
調用者不能創建一個安全級別更高的Delegate,也不能創建一個指向安全級別更高方法的Delegate。
CLR 4.0安全模型小結
本文介紹了CLR4.0中引入的三層安全級別以及運作機制,示例了安全級別的設置原則,講述了安全級別和類型系統的關聯。
【編輯推薦】