淺談CLR 4.0安全模型的運(yùn)作機(jī)制
CLR 4.0安全模型三層安全級(jí)別及其運(yùn)作機(jī)制
CLR4.0中的安全級(jí)別,從低到高排列如下:
Transparent
SafeCritical
Critical
其運(yùn)作機(jī)制如下圖所示,可以用三個(gè)箭頭加以說(shuō)明:
Transparent的代碼可以調(diào)用SafeCritical的代碼
SafeCritical的代碼可以調(diào)用Critical的代碼
Transparent的代碼不可以調(diào)用Critical的代碼
下面的代碼展示了安全級(jí)別的運(yùn)作機(jī)制:
1: using System;
2: using System.Security;
3:
4: // 這個(gè)屬性使得assembly中沒(méi)有Security標(biāo)記的方法默認(rèn)為T(mén)ransparent方法
5: [assembly:AllowPartiallyTrustedCallers]
6:
7: namespace SecurityLevel
8: {
9: public class Program
10: {
11: // 標(biāo)記Foo為Critical方法。
12: [SecurityCritical]
13: static void Foo()
14: {
15: Console.WriteLine("Hello Foo");
16: }
17:
18: static void Main()
19: {
20: // 這個(gè)調(diào)用會(huì)導(dǎo)致以下的異常:
21: // Unhandled Exception: System.MethodAccessException: SecurityLevel.Program.Foo()
22: // at SecurityLevel.Program.Main()
23: Foo();
24: }
25: }
26: }
Main函數(shù)由于沒(méi)有任何安全屬性,而且在assembly上有AllowPartiallyTrustedCallers屬性,所以他的安全級(jí)別是Transparent,根據(jù)前文提及的安全機(jī)制,不能直接調(diào)用Critical函數(shù)Foo,于是命令行上顯示了異常信息。
應(yīng)用安全級(jí)別構(gòu)筑體用程序
CLR 4.0安全模型提供了這樣的一個(gè)機(jī)制,用戶只有正確使用這些機(jī)制,才能構(gòu)筑健壯的應(yīng)用程序。在這里,“正確的使用”指的是合理的設(shè)置函數(shù)的安全級(jí)別,對(duì)三個(gè)安全級(jí)別設(shè)置的指導(dǎo)原則如下:
Critical:通常用來(lái)執(zhí)行高危操作,比如對(duì)文件系統(tǒng)的讀寫(xiě)。
SafeCritical:用來(lái)做安全方面的檢驗(yàn),或者只做限制性的操作。
Transparent:來(lái)自任何部分信任的程序代碼。
舉例來(lái)說(shuō),我們把三層模型應(yīng)用到cookie的讀寫(xiě)上,***層可以有一個(gè)Critical的函數(shù),用來(lái)在文件系統(tǒng)上寫(xiě)一個(gè)cookie文件。中間層有一個(gè)SafeCritical,用于檢驗(yàn)cookie操作的文件是否屬于特定的文件夾,就好像做一個(gè)安全檢查:如果通過(guò)了,則允許操作;否則的話就拒絕之。
下面的例子展示了一個(gè)簡(jiǎn)化后的應(yīng)用,從D盤(pán)的temp文件夾中刪除文件。請(qǐng)參見(jiàn)代碼中的注釋理解程序。
1: using System;
2: using System.IO;
3: using System.Security;
4:
5: // 這個(gè)屬性使得assembly沒(méi)有Security標(biāo)記的方法默認(rèn)為T(mén)ransparent方法
6: [assembly:AllowPartiallyTrustedCallers]
7:
8: namespace SecurityLevel
9: {
10: public class Program
11: {
12: /// <summary>
13: /// 該函數(shù)可以刪除文件系統(tǒng)上的任意函數(shù)。具有***的安全級(jí)別
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: /// 該函數(shù)驗(yàn)證待刪文件是否在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: // 該語(yǔ)句運(yùn)行正常
42: DeleteFileFromTemp(@"d:\temp\a.txt");
43:
44: // 該語(yǔ)句拋出異常
45: DeleteFileFromTemp(@"d:\a.txt");
46: }
47: }
48: }
49:
安全級(jí)別和.NET類型系統(tǒng)
理解了安全級(jí)別的應(yīng)用之后,我們來(lái)看看安全級(jí)別和.NET類型系統(tǒng)之間的關(guān)系:
安全級(jí)別和反射
反射機(jī)制提供了這樣三個(gè)屬性來(lái)探測(cè)一個(gè)類型(Type)和方法(MethodInfo)的安全級(jí)別
- IsSecurityCritical { get; }
- IsSecuritySafeCritical { get; }
- IsSecurityTransparent { get; }
大家可以觀察到,這三個(gè)屬性是只讀的,因?yàn)橥ǔ>硾r下,編譯器會(huì)寫(xiě)入了相關(guān)信息。
CLR 4.0安全模型的安全級(jí)別和繼承
以下兩點(diǎn)值得注意:關(guān)于類型,子類型的安全級(jí)別必須等于或者高于父類型的安全級(jí)別;關(guān)于方法,繼承的方法不能改變基類型方法的安全級(jí)別
安全級(jí)別和委托(Delegate)
調(diào)用者不能創(chuàng)建一個(gè)安全級(jí)別更高的Delegate,也不能創(chuàng)建一個(gè)指向安全級(jí)別更高方法的Delegate。
CLR 4.0安全模型小結(jié)
本文介紹了CLR4.0中引入的三層安全級(jí)別以及運(yùn)作機(jī)制,示例了安全級(jí)別的設(shè)置原則,講述了安全級(jí)別和類型系統(tǒng)的關(guān)聯(lián)。
【編輯推薦】