2009-03-02 7 views
4

In diesem Code möchte ich, dass die ReadFileSystem-Methode verboten ist, eine Berechtigung für das Dateisystem zu bestätigen.Wie kann man die Verwendung von CAS verweigern?

Ich erwartete, dass dies auf fileIo.Assert() werfen wird, aber es tut es nicht. Warum?

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

aktualisiert

Großer Link hier auf CAS: http://blogs.msdn.com/shawnfa/archive/2004/08/25/220458.aspx

Antwort

8

Der nachfolgende Assert negiert die Auswirkungen von Deny.

Die Fähigkeit, FileIOPermission zu bestätigen, hängt hauptsächlich davon ab, ob Ihre Assembly vertrauenswürdig ist. Es ist nicht von einem früheren Verweigern von FileIOPermission betroffen. Es stellt sich heraus, dass es auch nicht von der vorherigen Ablehnung der Assertion SecurityPermission betroffen ist. Dies liegt daran, dass SecurityPermissionFlag.Assertion als Verbindungszeitanforderung aktiviert ist. Dies ist nicht eindeutig dokumentiert; Ich fand es here.

Um zu erzwingen, dass die CLR Ihrer Assembly für FileIOPermission nicht vertraut, können Sie nach den using-Anweisungen oben in der Datei Folgendes verwenden: Wenn Sie dies zu Ihrer Datei hinzufügen, wird die Bestätigung nicht wirksam. Dies betrifft die gesamte Baugruppe. Es gibt keine feinere Granularität.

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

Binärcodierer ist genau richtig. .NET wird nur selten intern bestätigt ... Es erfordert normalerweise. Nachfrage ist, was der Stack laufen wird, der die Verweigerung auf dem Stack finden und scheitern würde. Für alle Datei-IO macht .NET eine Nachfrage. Sobald jedoch eine Assert auf dem Stack gefunden wird, wird der Stack Walk kurz angehalten. –

+0

Und wie der Binärcodierer vorgeschlagen wurde, besteht die einzige Möglichkeit, Assert von seiner Arbeit abzuhalten, darin, der gesamten Assembly die Berechtigungen zu verweigern, die Sie geltend machen möchten. Dadurch wird Ihre Assembly effektiv mit partieller Vertrauenswürdigkeit ausgeführt. Partielles Vertrauen ist gut, aber wenn Sie Assert nicht anrufen wollen, rufen Sie es einfach nicht an. –

+0

@Andrew, ich wollte sicher sein, dass jeder Anruf nach meiner Assert nicht auf die Festplatte zugreifen kann. Weil mein Anwendungsfall war, eine andere Assembly über Reflektion aufzurufen (nicht vertrauenswürdig), ohne den Beweis konfigurieren zu müssen, wenn ich ihn lade. Endlich ist es das, was ich getan habe. Aber dieses Verhalten von CAS hat mich fasziniert. –

1

Gute Frage sicher. Ich habe den Code ausgeführt und bin auch etwas verwirrt. Ich verbringe nur eine Stunde oder 2 Stunden damit, die Docs zu studieren und zu googeln, aber ohne Erfolg. Beachten Sie, dass MSDN durch eine Anforderung auf die Berechtigung Assertion verhindert.

Bearbeiten: binarycoders Antwort wies mich in die richtige Richtung.

Die Asserion-Rechte sind einfach nicht effektiv in einer Vollschub-Baugruppe. Nur wenn Sie Folgendes am Anfang der Datei hinzufügen:

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

Der Aufruf von fileIo.Assert() wird fehlschlagen.

Aber ansonsten, versuchen, zu verweigern() die Berechtigung Assertion und das folgende Attribut sind völlig ineffektiv (es sei denn, Sie explizit verlangen() die Assertion Rechte).

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

In der Dokumentation wird das Assert() ‚einige Sicherheitsprobleme hat‘ und die Empfehlung ist immer der Nachfrage-before-Assert:

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

aber ich muss noch meine Einstellung nachjustieren über die Anwendung des Prinzips des geringsten Privilegs.

+0

Warum sollten wir danach verlangen und behaupten? Können Sie mir Ihre Quelle geben? Denn wenn Demand Ok ist, verstehe ich nicht, warum wir eine Assertion danach machen sollen. Ich erinnerte mich daran, etwas über dieses Muster gelesen zu haben, um Berechtigungen zu konvertieren (zB IOPermission + SecurityPermission => CustomPermission). –

+0

Die einzige Quelle, die ich habe, ist ein Powerpoint: http://www.bristowe.com/presentations/Code%20Access%20Security.ppt Grundsätzlich ist die Nachfrage Ihre Überprüfung und die Assert eine Beschleunigung für Downstream-Code. –

2

Ich denke, Sie können den Zweck der Geltendmachung von Berechtigungen missverstehen. Wenn Sie einen Berechtigungssatz in CAS bestätigen, sagen Sie effektiv "Ich weiß, was ich tue ... mir ist es egal, welche Berechtigungen tiefer im Stapel liegen." Das ist fast nie was Sie wollen. Im Allgemeinen möchten Sie einen Berechtigungssatz anfordern. Das führt zu einem Stackwalk, der Deny auf dem Stapel findet und dann eine Sicherheitsausnahme verursacht.

Allerdings seit.In NET sind praktisch alle erforderlichen Anforderungen enthalten. Es besteht nur selten die Notwendigkeit, tatsächlich etwas anzufordern, es sei denn, Sie führen Asserts durch (auch das ist selten) oder Sie haben Ihre eigene benutzerdefinierte Berechtigungsklasse geschrieben.

+0

Ja, ich weiß das, aber ich dachte, dass wenn wir Assert machen, es einen Stack für die SecurityPermission gäbe. (Die MSDN sagt deutlich, dass Sie bestätigen können, dass Ihre Assembly über die Berechtigung für die geltend gemachte Berechtigung verfügt und dass Sie SecurityPermission für Ihre Assembly erteilt haben). –

+0

Keines dieser Dinge, die MSDN sagt, erfordert einen Stack-Walk. –

+0

Sicher, es war mein Fehler. Aber Ihre Assembly sollte mit der SecurityPermission und dem Assertion Flag erlaubt sein. (In der Konfiguration von .NET oder in Ihrem Assembler-Code wie Binär-Codierer sagte) –

Verwandte Themen