Verwenden der Assert-Methode

Aktualisiert: November 2007

Assert ist eine Methode, die für Klassen von Codezugriffsberechtigungen und für die PermissionSet-Klasse aufgerufen werden kann. Sie können den Code und nachgeschaltete Aufrufer mit Assert aktivieren. Dadurch können Aktionen ausgeführt werden, für die der Code, u. U. jedoch nicht der Aufrufer über die entsprechende Berechtigung verfügt. Eine Sicherheitsassertion ändert den normalen Prozess, der von der Laufzeit während einer Sicherheitsüberprüfung ausgeführt wird. Wenn Sie eine Berechtigung mit Assert anfordern, wird das Sicherheitssystem angewiesen, die Aufrufer des Codes nicht auf die Assertionsberechtigung zu überprüfen.

Vorsicht:

Verwenden Sie Assertionen mit Bedacht, da sie zu Sicherheitslücken führen und das Verfahren beeinträchtigen können, mit dem die Common Language Runtime Sicherheitsbeschränkungen erzwingt.

Assertionen empfehlen sich in Situationen, in denen eine Bibliothek nicht verwalteten Code aufruft oder einen Aufruf vornimmt, für den eine Berechtigung erforderlich ist, die offensichtlich nicht dem eigentlichen Zweck der Bibliothek entspricht. Beispielsweise muss verwalteter Code, der unverwalteten Code aufruft, über SecurityPermission mit einem festgelegten UnmanagedCode-Flag verfügen. Wenn Code nicht vom lokalen Computer stammt, sondern z. B. aus dem lokalen Intranet geladen wurde, wird ihm diese Berechtigung nicht standardmäßig erteilt. Daher muss bei aus dem lokalen Intranet geladenen Code die Berechtigung durch die Bibliothek mittels Assert angefordert werden, damit dieser Code eine Bibliothek aufrufen kann, die unverwalteten Code verwendet. Darüber hinaus nehmen einige Bibliotheken evtl. Aufrufe vor, die für Aufrufer nicht sichtbar und für die besondere Berechtigungen erforderlich sind.

Sie können Assertionen auch in Situationen anwenden, in denen der Zugriff von Code auf eine Ressource für Aufrufer vollständig verborgen abläuft. Angenommen, die Bibliothek erhält Informationen aus einer Datenbank. Bei diesem Vorgang werden jedoch auch Informationen aus der Registrierung des Computers gelesen. Da Entwickler, die mit der Bibliothek arbeiten, nicht auf die Quelle zugreifen können, können sie nicht wissen, dass ihr Code für die Verwendung des Codes über RegistryPermission verfügen muss. Wenn Sie in diesem Fall entscheiden, dass es nicht sinnvoll oder erforderlich ist, dass die Aufrufer des Codes über die Berechtigung für den Zugriff auf die Registrierung verfügen, können Sie die Berechtigung zum Lesen der Registrierung als Assertion anfordern. In dieser Situation empfiehlt es sich für die Bibliothek, die Berechtigungen mit Assert anzufordern, sodass Aufrufer ohne RegistryPermission die Bibliothek verwenden können.

Die Assertion wirkt sich nur auf den Stackwalk aus, wenn die Assertionsberechtigung und eine von einem nachgeschalteten Aufrufer geforderte Berechtigung von demselben Typ sind und die geforderte Berechtigung eine Teilmenge der Assertionsberechtigung darstellt. Wenn Sie z. B. FileIOPermission für das Lesen aller Dateien auf Laufwerk C mit Assert anfordern, und es wird eine nachgeschaltete Forderung vorgenommen, dass FileIOPermission Dateien in C:\Temp lesen darf, wirkt sich die Assertion u. U. auf den Stackwalk aus. Wenn jedoch gefordert wird, dass FileIOPermission auf Laufwerk C schreiben darf, hat die Assertion keine Auswirkung.

Zum Ausführen von Assertionen muss dem Code sowohl die Berechtigung erteilt werden, die mit Assert angefordert wird, als auch die SecurityPermission, die das Recht zum Ausführen von Assertionen darstellt. Obwohl Sie eine Berechtigung mit Assert anfordern könnten, die dem Code nicht erteilt wurde, wäre die Assertion sinnlos, da die Sicherheitsüberprüfung fehlschlägt, bevor die Assertion ihre erfolgreiche Ausführung bewirken kann.

Die folgende Abbildung veranschaulicht die Vorgänge bei der Verwendung von Assert. Angenommen, die folgenden Aussagen gelten für die Assemblys A, B, C, E und F und die beiden Berechtigungen B1 und B1A:

  • B1A stellt das Recht zum Lesen von TXT-Dateien auf Laufwerk C dar.

  • B1 stellt das Recht zum Lesen aller Dateien auf Laufwerk C dar.

  • Sowohl B1A als auch B1 sind vom Typ FileIOPermissions, und B1A ist eine Teilmenge von B1.

  • Den Assemblys E und F wurde die Berechtigung B1A erteilt.

  • Assembly C wurde die Berechtigung B1 erteilt.

  • Den Assemblys A und B wurde weder die Berechtigung B1 noch die Berechtigung B1A erteilt.

  • Methode A ist in Assembly A enthalten, Methode B ist in Assembly B enthalten usw.

Verwenden von "Assert"

In diesem Szenario ruft Methode A B auf, B ruft C auf, C ruft E auf, und E ruft F auf. Methode C fordert die Berechtigung zum Lesen von Dateien auf Laufwerk C mit Assert an (Berechtigung B1), und Methode E fordert die Berechtigung zum Lesen von TXT-Dateien auf Laufwerk C (Berechtigung B1A). Wenn die Forderung zur Laufzeit in F gefunden wird, findet ein Stackwalk zum Überprüfen der Berechtigungen aller Aufrufer von F statt, wobei mit E begonnen wird. E wurde die Berechtigung B1A erteilt, sodass der Stackwalk mit der Untersuchung der Berechtigungen von C fortfährt, wobei die Assertion von C entdeckt wird. Da die geforderte Berechtigung (B1A) eine Teilmenge der Assertionsberechtigung (B1) darstellt, wird der Stackwalk beendet, und die Sicherheitsüberprüfung wird automatisch erfolgreich abgeschlossen. Es spielt keine Rolle, dass den Assemblys A und B die Berechtigung B1A nicht erteilt wurde. Durch die Assertion von B1 gewährleistet Methode C, dass ihre Aufrufer auf die von B1 geschützte Ressource zugreifen können, selbst wenn den Aufrufern nicht die Berechtigung für den Zugriff auf die Ressource erteilt wurde.

Wenn Sie eine Klassenbibliothek entwerfen und eine Klasse auf eine geschützte Ressource zugreift, müssen Sie in den meisten Fällen eine Sicherheitsforderung vornehmen, die erfordert, dass die Aufrufer der Klasse über die entsprechende Berechtigung verfügen. Wenn die Klasse anschließend eine Operation durchführt, bei der Sie wissen, dass die meisten Aufrufer nicht über die entsprechende Berechtigung verfügen, und wenn Sie für den Zugriff dieser Aufrufer auf den Code die Verantwortung übernehmen möchten, können Sie die Berechtigung als Assertion anfordern, indem Sie die Assert-Methode für ein Berechtigungsobjekt aufrufen, das die vom Code ausgeführte Operation darstellt. Durch eine solche Verwendung von Assert können Aufrufer den Code aufrufen, die dazu normalerweise nicht berechtigt sind. Wenn Sie also eine Berechtigung mit Assert anfordern, sollten Sie die notwendigen Sicherheitsüberprüfungen unbedingt vorab durchführen, um den Missbrauch der Komponente auszuschließen.

Angenommen, die Klasse der hoch vertrauenswürdigen Bibliothek verfügt über eine Methode zum Löschen von Dateien. Sie greift auf die Datei durch Aufrufen einer nicht verwalteten Win32-Funktion zu. Ein Aufrufer ruft die Delete-Methode des Codes auf, wobei er den Namen der zu löschenden Datei, C:\Test.txt, übergibt. In der Delete-Methode erstellt der Code ein FileIOPermission-Objekt, das den Schreibzugriff auf C:\Test.txt darstellt. (Zum Löschen einer Datei ist Schreibzugriff erforderlich.) Der Code ruft anschließend eine imperative Sicherheitsüberprüfung auf, indem er die Demand-Methode des FileIOPermission-Objekts aufruft. Wenn einer der Aufrufer in der Aufrufliste nicht über diese Berechtigung verfügt, wird eine SecurityException ausgelöst. Wenn keine Ausnahme ausgelöst wird, können Sie sicher sein, dass alle Aufrufer zum Zugriff auf C:\Test.txt berechtigt sind. Da davon auszugehen ist, dass die meisten Aufrufer keine Zugriffsberechtigung für nicht verwalteten Code haben, erstellt der Code anschließend ein SecurityPermission-Objekt, das das Recht zum Aufrufen von nicht verwaltetem Code darstellt und die Assert-Methode des Objekts aufruft. Schließlich wird die nicht verwaltete Win32-Funktion aufgerufen, um C:\Test.txt zu löschen, und der Aufrufer erhält wieder die Kontrolle.

Vorsicht:

Achten Sie unbedingt darauf, dass der Code keine Assertionen in Situationen verwendet, in denen anderer Code Ihren Code für den Zugriff auf eine Ressource verwenden kann, die durch die von Ihnen mit Assert angeforderte Berechtigung geschützt ist. Fordern Sie beispielsweise in Code, der in eine Datei schreibt, deren Name vom Aufrufer als Parameter angegeben wird, nicht die FileIOPermission zum Schreiben in Dateien mit Assert an, da der Code durch Dritte missbraucht werden könnte.

Wenn Sie die imperative Sicherheitssyntax verwenden, wird durch den Aufruf der Assert-Methode für mehrere Berechtigungen in derselben Methode eine Sicherheitsausnahme ausgelöst. Stattdessen müssen Sie ein PermissionSet-Objekt erstellen, dieses an die einzelnen aufzurufenden Berechtigungen übergeben und anschließend die Assert-Methode für das PermissionSet-Objekt aufrufen. Sie können die Assert-Methode mehr als einmal aufrufen, wenn Sie die deklarative Sicherheitssyntax verwenden.

Das folgende Beispiel veranschaulicht die deklarative Syntax für das Überschreiben von Sicherheitsüberprüfungen mithilfe der Assert-Methode. Beachten Sie, dass die FileIOPermissionAttribute-Syntax zwei Werte enthält: eine SecurityAction-Enumeration und den Speicherort der Datei bzw. des Verzeichnisses, für den die Berechtigung erteilt werden soll. Der Aufruf von Assert bewirkt die erfolgreiche Ausführung von Forderungen für den Zugriff auf C:\Log.txt, selbst wenn der Aufrufer nicht auf die Berechtigung für den Zugriff auf die Datei überprüft wird.

[Visual Basic]

Option Explicit
Option Strict

Imports System
Imports System.IO
Imports System.Security.Permissions

Namespace LogUtil
   Public Class Log
      Public Sub New()

      End Sub

     <FileIOPermission(SecurityAction.Assert, All := "C:\Log.txt")> Public Sub 
      MakeLog()
         Dim TextStream As New StreamWriter("C:\Log.txt")
         TextStream.WriteLine("This  Log was created on {0}", DateTime.Now) '
         TextStream.Close()
      End Sub
   End Class
End Namespace
namespace LogUtil
{
   using System;
   using System.IO;
   using System.Security.Permissions;

   public class Log
   {
      public Log()
      {    
      }   
      [FileIOPermission(SecurityAction.Assert, All = @"C:\Log.txt")]
      public void MakeLog()
      {   
         StreamWriter TextStream = new StreamWriter(@"C:\Log.txt");
         TextStream.WriteLine("This  Log was created on {0}", DateTime.Now);
         TextStream.Close();
      }
   }
} 

Das folgende Codefragment veranschaulicht die imperative Syntax für das Überschreiben von Sicherheitsüberprüfungen mithilfe der Assert-Methode. In diesem Beispiel wird eine Instanz des FileIOPermission-Objekts deklariert. FileIOPermissionAccess.AllAccess wird an seinen Konstruktor übergeben, um den Typ des zulässigen Zugriffs zu definieren, gefolgt von einer Zeichenfolge, die den Speicherort der Datei beschreibt. Nach Definition des FileIOPermission-Objekts müssen Sie nur seine Assert-Methode aufrufen, um die Sicherheitsüberprüfung zu überschreiben.

[Visual Basic]

Option Explicit
Option Strict
Imports System
Imports System.IO
Imports System.Security.Permissions
Namespace LogUtil
   Public Class Log
      Public Sub New()
      End Sub 'New
      
      Public Sub MakeLog()
         Dim FilePermission As New FileIOPermission(FileIOPermissionAccess.AllAccess, "C:\Log.txt")
         FilePermission.Assert()
         Dim TextStream As New StreamWriter("C:\Log.txt")
         TextStream.WriteLine("This  Log was created on {0}", DateTime.Now)
         TextStream.Close()
      End Sub
   End Class
End Namespace 
namespace LogUtil
{
   using System;
   using System.IO;
   using System.Security.Permissions;

   public class Log
   {
      public Log()
      {    
      }   
      public void MakeLog()
      {
         FileIOPermission FilePermission = new FileIOPermission(FileIOPermissionAccess.AllAccess,@"C:\Log.txt"); 
         FilePermission.Assert();
         StreamWriter TextStream = new StreamWriter(@"C:\Log.txt");
         TextStream.WriteLine("This  Log was created on {0}", DateTime.Now);
         TextStream.Close();
      }
   }
}

Siehe auch

Konzepte

Überschreiben von Sicherheitsüberprüfungen

Sicherheitsforderungen

Referenz

PermissionSet

SecurityPermission

FileIOPermission

SecurityAction

Weitere Ressourcen

Erweitern von Metadaten mithilfe von Attributen

Codezugriffssicherheit