2009-03-02 53 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類,否則幾乎不需要實際需求。