6

我正在研究代码访问安全性。我费了一番脑筋,所以我想我最终会使用 Reflector 并开始研究 .NET 4.0 如何使用安全属性。

观察

System.IO.File.Delete方法用[SecuritySafeCritical]属性修饰。

System.IO.File.Delete方法委托给一个内部方法InternalDelete,该方法使用该[SecurityCritical]属性进行修饰。

我在我的一个名为DeleteFile的 MVC 应用程序类中有一个方法,它正在运行SecurityTransparent(我通过检查DeleteFile的 MethodInfo.IsSecurityCritical 属性进行了验证)

权限

根据我目前的理解,这意味着:

  1. System.IO.File.Delete 可以调用InternalDelete,因为[SecuritySafeCritical]方法可以调用[SecurityCritical],因此不会引发 SecurityException。
  2. DeleteFile可以调用 System.IO.File.Delete 因为[SecurityTransparent]可以调用[SecuritySafeCritical]

所以基本上,在不调整任何开箱即用的安全设置的情况下,这段代码将成功删除一个名为 test.txt 的虚拟文件

namespace MyTestMvcApp
{
    public class FileHelpers()
    {
        // Has SecurityTransparent
        public void DeleteFile()
        {
            // Will succesfully delete the file
            File.Delete("test.txt");
        }
    }
}

混乱

在 的InternalDelete方法中System.IO.File.Delete,它使用该CodeAccessPermission.Demand方法检查堆栈上的所有调用者是否具有必要的权限。我不太明白的是 MSDN 文档中的这一行CodeAccessPermission.Demand

不检查调用该方法的代码的权限;检查从该代码的直接调用者开始,并继续向上堆栈。

所以我的问题是,如果我的应用程序的DeleteFile方法是SecurityTransparent,为什么允许调用SecurityCritical方法?

这可能是一个损坏的示例,可能缺少一些概念,但正如我所说,我仍在思考它,人们可以提供的任何见解越多,我就越会加深我的理解。

谢谢

4

1 回答 1

0

您正在混淆两种 CAS 执行机制。虽然他们确实有一些互动,但它与您似乎担心的方式并不完全相同。对于以 Demand 为代表的完全许可要求,它们本质上是独立的。

CLR 在执行代码之前应用透明度验证。如果通过,CLR 将验证通过属性应用的任何声明性 CAS 要求。如果这些通过(或不存在),CLR 将执行代码,此时命令式(内联)需求将运行。

有关“不检查调用此方法的代码的权限”的 Demand 文档说明适用于 Demand 方法本身。换句话说,如果您有一个调用 Demand 的方法 Foo,则验证的调用堆栈将启动 Foo 的调用者,而不是 Foo 本身。例如,如果您有调用链A -> B -> C -> Foo -> Demand,则仅验证 A、B 和 C 以检查它们是否具有授予的权限。

于 2012-06-04T14:18:26.127 回答