2009-03-02 70 views
4

在这段代码中,我希望ReadFileSystem方法被禁止在文件系统上声明一个权限。如何否认CAS断言?

我预计这会抛出fileIo.Assert(),但它没有。为什么?

using System.Security.Permissions; 
static void Main(string[] args) 
{ 
    var fileIo = new FileIOPermission(PermissionState.Unrestricted); 
    var secuPerm = new SecurityPermission(SecurityPermissionFlag.Assertion); 
    PermissionSet set = new PermissionSet(PermissionState.Unrestricted); 
    set.AddPermission(fileIo); 
    set.AddPermission(secuPerm); 
    set.Deny(); 
    ReadFileSystem(); 
    Console.Read(); 
} 

private static void ReadFileSystem() 
{ 
    var fileIo = newFileIOPermission(PermissionState.Unrestricted); 
    fileIo.Assert(); 

    DirectoryInfo dir = new DirectoryInfo("C:/"); 
    dir.GetDirectories(); 
} 

更新

伟大的链接在这里CAS:http://blogs.msdn.com/shawnfa/archive/2004/08/25/220458.aspx

回答

8

随后的Assert否定Deny的影响。

断言FileIOPermission的能力主要取决于您的程序集是否可信。它不受FileIOPermission的先前Deny影响。事实证明,它也不会受到以前声明SecurityPermission的拒绝的影响。 这是因为SecurityPermissionFlag.Assertion被检查为链接时间需求。这没有明确记录;我发现它here

要强制CLR不信任FileIOPermission的程序集,可以在using语句之后的文件顶部使用以下内容。当你将它添加到你的文件中时,assert将不会生效。这会影响整个装配。没有更好的粒度。

[assembly:FileIOPermission(SecurityAction.RequestRefuse, Unrestricted=true)] 
+0

binarycoder是完全正确的。 .NET很少在内部声明......它通常需要。需求是什么堆栈走,会发现拒绝堆栈和失败。对于所有文件,IO .NET都需要。但是一旦它在栈上发现一个断言,栈走就停止了。 – 2009-03-08 10:12:29

1

肯定好问题。我运行代码,也有点神秘。 我只花了一个小时或2研究文档和谷歌搜索,但无济于事。请注意,MSDN通过对断言权限执行“请求”进行警报。

编辑:binarycoder的答案指出我正确的方向。

Asserion权利是根本无效在全推力组件。只有在文件顶部添加以下内容:

[assembly: SecurityPermissionAttribute(SecurityAction.RequestRefuse, Assertion = true)] 

对fileIo.Assert()的调用将失败。

但是否则,尝试拒绝()断言权限和以下属性是完全无效的(除非您明确要求()断言权限)。

[SecurityPermissionAttribute(SecurityAction.Deny, Assertion = true)] 
private static void ReadFileSystem() {} 

文档确实状态断言()“有一些安全问题”和建议是总是要求前方的断言:

fileIo.Demand(); 
fileIo.Assert(); 

,但我还是要重新调整我的心态关于应用最小特权原则。

+0

我们为什么要求和断言? 你能给我你的来源吗?因为如果需求是好的,我不明白为什么我们应该做一个断言。我记得读过关于这种模式的一些东西,它是转换权限(例如IOPermission + SecurityPermission => CustomPermission)。 – 2009-03-08 15:46:36

+0

我得到的唯一来源是一个简报:http://www.bristowe.com/presentations/Code%20Access%20Security.ppt 基本上,需求是您的支票,并声明加快下游代码。 – 2009-03-08 16:01:42

2

我想你可能会误解断言权限的目的。当您在CAS中声明权限时,您实际上是在说“我知道我在做什么......我不在乎堆栈中的权限更深。”这几乎是从来没有你想要什么。您通常需要一个权限集。这会导致栈走,它会在栈上找到Deny,然后导致安全异常。

但是,因为。NET几乎具有所有必需的内置需求,除非您正在执行Asserts(很少见),或者您已编写自己的自定义Permission类,否则几乎不需要实际需求。