質問
このコードでは、ReadFileSystemメソッドがファイルシステムのパーミッションをアサートすることを禁止したいです。
これは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
解決
後続のアサートは、拒否の効果を無効にします。
FileIOPermissionをアサートする機能は、主にアセンブリが信頼できるかどうかに依存します。以前のFileIOPermissionの拒否の影響を受けません。また、以前のアサーションの拒否SecurityPermissionの影響も受けないことがわかります。 これは、リンク許可要求としてSecurityPermissionFlag.Assertionがチェックされるためです。これは明確に文書化されていません。 ここで見つけました。
FileIOPermissionのアセンブリをCLRに信頼させないようにするには、usingステートメントに続いてファイルの先頭で次を使用できます。これをファイルに追加すると、アサートは有効になりません。これは、アセンブリ全体に影響します。より細かい粒度はありません。
[assembly:FileIOPermission(SecurityAction.RequestRefuse, Unrestricted=true)]
他のヒント
権限をアサートする目的を誤解する可能性があると思います。 CASでアクセス許可セットをアサートすると、「私は何をしているのかわかっています...スタックのどのアクセス許可がより深いかは気にしません」と言うことになります。それはほとんどあなたが望むものではありません 。通常、許可セットを要求します。これにより、スタックウォークが発生し、スタックで拒否が検出され、セキュリティ例外が発生します。
ただし、.NETには必要なDemandがほぼすべて組み込まれているため、Assertsを実行する場合(これも珍しいことです)、または独自のカスタムPermissionクラスを記述していない限り、実際に何かを要求する必要はほとんどありません。
確かに良い質問です。私はコードを実行しましたが、少し神秘的です。 私は1時間か2時間だけドキュメントを勉強してグーグルで勉強しましたが、役に立ちませんでした。 MSDNは、アサーション許可の要求を行うことで対処します。
編集:binarycoderの答えにより、正しい方向に導かれました。
アサーリオンの権利は、フルスラストアセンブリでは有効ではありませんです。ファイルの先頭に次を追加した場合のみ:
[assembly: SecurityPermissionAttribute(SecurityAction.RequestRefuse, Assertion = true)]
fileIo.Assert()の呼び出しは失敗します。
ただし、そうでない場合、アサーション権限と次の属性を拒否()しようとすると、完全に無効になります(明示的にアサーション権をDemand()しない限り)。
[SecurityPermissionAttribute(SecurityAction.Deny, Assertion = true)]
private static void ReadFileSystem() {}
ドキュメントには、Assert()には「セキュリティ上の問題がある」と記載されており、推奨事項は常にDemand-before-Assertにすることです:
fileIo.Demand();
fileIo.Assert();
しかし、最小特権の原則を適用することについては、自分の考え方を再調整する必要があります。