CLR 4.0 安全模型

    技术2022-05-11  2

    在公共语言运行时(CLR)过往的版本中,安全模型一直是最为复杂的模块之一,由于涉及Evidence,CAS策略等机制,难以被用户使用。在Silverlight中,CLR团队提出了三层安全级别,大大简化了安全模型,得到了很多积极的反馈。所以CLR4.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提供了这样的一个机制,用户只有正确使用这些机制,才能构筑健壮的应用程序。在这里,“正确的使用”指的是合理的设置函数的安全级别,对三个安全级别设置的指导原则如下:

    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: /// 13: /// 该函数可以删除文件系统上的任意函数。具有最高的安全级别 14: /// 15: /// 文件名 16: [SecurityCritical] 17: static void DeleteFile(string fileName) 18: { 19: File.Delete(fileName); 20: } 21: 22: /// 23: /// 该函数验证待删文件是否在d:/temp中 24: /// 25: /// 待删文件名 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; }

    大家可以观察到,这三个属性是只读的,因为通常境况下,编译器会写入了相关信息。

    安全级别和继承

    以下两点值得注意:关于类型,子类型的安全级别必须等于或者高于父类型的安全级别;关于方法,继承的方法不能改变基类型方法的安全级别

    安全级别和委托(Delegate)

    调用者不能创建一个安全级别更高的Delegate,也不能创建一个指向安全级别更高方法的Delegate。

    小结

    本文介绍了CLR4.0中引入的三层安全级别以及运作机制,示例了安全级别的设置原则,讲述了安全级别和类型系统的关联。

      .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }

    最新回复(0)