2009-03-02 6 views
4

このコードでは、ReadFileSystemメソッドがファイルシステムのアクセス許可をアサートすることを禁止したいと思います。CASでアサートを拒否する方法は?

これはfileIo.Assert()でスローされると予想しましたが、そうではありません。どうして? CASにここ

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(); 
} 

更新

グレートリンク:確かにhttp://blogs.msdn.com/shawnfa/archive/2004/08/25/220458.aspx

答えて

8

次のアサートは、拒否の影響を否定します。

FileIOPermissionをアサートする機能は、主にアセンブリが信頼できるかどうかによって異なります。以前のFileIOPermissionの拒否の影響を受けません。以前のAssertion SecurityPermissionの拒否の影響を受けていないことが判明しました。 これは、SecurityPermissionFlag.Assertionがリンク時の要求としてチェックされているためです。これは明確に文書化されていません。私はそれを見つけたhere

CLRがFileIOPermissionのアセンブリを信頼しないようにするには、ファイルの先頭にusingステートメントを使用します。これをファイルに追加すると、アサートは有効になりません。これはアセンブリ全体に影響します。細かい細かさはありません。

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

binarycoderはまさに正しいです。 .NETはめったに内部的にアサートしません...通常は要求します。デマンドは、スタック上を拒否して失敗するスタックが何をするのかを示します。すべてのファイルIOに対して.NETは要求を行います。しかし、スタック上にAssertが見つかるとすぐに、スタックウォークは短く止められます。 –

+0

バイナリコーダが示唆しているように、Assertの作業を邪魔にならない唯一の方法は、アサートしようとしているパーミッションをアセンブリ全体で拒否し、アセンブリを部分的な信頼で効果的に実行させることです。部分的な信頼は良いですが、Assertを呼びたくない場合は、単に呼び出さないでください。 –

+0

@Andrew、私はAssert後の呼び出しがハードドライブにアクセスできないようにしたいと思っていました。私のユースケースは、ロード時に証拠を設定することなく、リフレクション(信頼できない)を介して別のアセンブリを呼び出すことでした。最後に、私がやったことです。しかし、このCASの動作は興味をそそられました。 –

1

良い質問。私はコードを実行し、少しも神秘的です。 私はちょうど1時間か2時間をかけてドキュメントやグーグルを勉強しているが役に立たない。アサーションのアクセス許可の要求を行うことで、MSDNが暴走することに注意してください。

編集:binarycoderの答えは正しい方向に私を指摘しました。

アサーションの権利はであり、フルスラストアセンブリでは効果的ではありません。

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

fileIo.Assert()の呼び出しは失敗します。

しかし、そうでなければ、Assertion権限とそれに続く属性をDeny()しようとすると、(Assertion権限を明示的に要求しない限り)全く効果がありません。

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

ドキュメントがアサートは()「いくつかのセキュリティ上の問題を持っている」という状態を行い、勧告は、常に需要ビフォアアサートすることです:

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

が、私はまだ私の考え方を再調整する必要が最小特権の原則を適用することについて

+0

私たちはなぜ要求し、後に主張すべきですか? 私にあなたのソースを教えてもらえますか?デマンドがOKならば、なぜ私たちは後にアサーションをしなければならないのか分からないからです。私はこのパターンについて何かを読んでいたことを思い出しました。それは許可を変換することでした(例えば、IOPermission + SecurityPermission => CustomPermission)。 –

+0

私が持っている唯一のソースはパワーポイントです:http://www.bristowe.com/presentations/Code%20Access%20Security.ppt 基本的には、デマンドはあなたのチェックであり、Assertはダウンストリームコードのスピードアップです。 –

2

私はあなたがパーミッションをアサートする目的を誤解していると思います。 CASに設定されているアクセス許可をアサートすると、「実際に何をしているのか知っています...アクセス権がどのように深いのかは気にしません」それはほとんどです。決してあなたが望むものです。一般的には、権限セットを要求する必要があります。その結果、スタックウォークが発生し、スタック上でDenyが検出され、セキュリティ例外が発生します。

ただし、以来。NETには事実上すべての必要なDemandsが組み込まれていますが、Assertsをやっていない限り、実際にDemandを行う必要はほとんどありません。

+0

はい私はそれを知っていますが、Assertを実行するときにSecurityPermissionのスタックウォークがあったと思いました。 (MSDNには、アセンブリにアサートされたアクセス許可のアクセス許可があり、アセンブリに対してSecurityPermissionが付与されていることをアサートできることが明確に記載されています)。 –

+0

MSDNで述べられていることは、スタックウォークを必要としません。 –

+0

確かに、それは私の間違いでした。しかし、あなたのアセンブリはSecurityPermissionとAssertionフラグで許可されるべきです。 (.NETの設定またはバイナリコーダのようなアセンブリコード内で) –

関連する問題