Použití metody Assert
Assert je metoda, kterou lze volat na třídy oprávnění přístupu ke kódu a na třídu PermissionSet. Metodu Assert můžete použít k tomu, abyste vašemu kódu povolili (a volajícím směru server-klient) provedení akcí, ke kterým váš kód má oprávnění k provedení, ale jeho volající je mít nemusí. Kontrolní výrazy zabezpečení mění normální proces, který provádí modul runtime během kontroly zabezpečení. Když uplatňujete oprávnění, tak to říká systému zabezpečení, aby nekontroloval volající vašeho kódu pro uplatňované oprávnění.
Upozornění |
---|
Používejte výrazy opatrně, protože mohou otevřít bezpečnostní díry a narušují mechanismus modulu runtime pro vynucování omezení zabezpečení. |
Výrazy jsou užitečné v situacích, ve kterých knihovna volá nespravovaný kód nebo provádí volání vyžadující oprávnění, které zjevně nesouvisí se zamýšleným použitím této knihovny. Například všechen spravovaný kód, který volá nespravovaný kód musí mít specifikovanou SecurityPermission s příznakem UnmanagedCode . Kód, který nepochází z místního počítače, jako je například kód stažený z místního intranetu, by neměl implicitně mít uděleno toto oprávnění. Proto aby kód, který je stažen z místního intranetu, byl schopen volat knihovnu, která používá nespravovaný kód, musí mít oprávnění uplatňovaná knihovnou. Kromě toho některé knihovny mohou provádět volání, která nejsou viditelná pro volající a vyžadují zvláštní oprávnění.
Můžete také použít výrazy v situacích, ve kterých váš kód přistupuje k prostředkům takovým způsobem, který je volajícím úplně skrytý. Předpokládejme například, že vaše knihovna získává informace z databáze, ale v procesu také čte informace z registru počítače. Protože vývojáři používající vaši knihovnu nemají přístup k vašemu zdrojovému kódu, vůbec neví, že jejich kód vyžaduje RegistryPermission , aby bylo možné použít váš kód. V tomto případě, pokud se rozhodnete, že není přiměřené nebo nezbytné vyžadovat, aby volající vašeho kódu měli oprávnění pro přístupu k registru, můžete uplatnit oprávnění pro čtení v registru. V takovém případě je pro knihovnu vhodné uplatnit oprávnění tak, aby volající bez RegistryPermission mohli používat knihovnu.
Kontrolní výraz ovlivňuje procházení zásobníku pouze v případě, jsou-li uplatňovaná oprávnění a oprávnění požadovaná volajícími ve směru server-klient stejného typu a je-li požadované oprávnění podmnožinou uplatňovaného oprávnění. Například pokud uplatňujete FileIOPermission pro čtení všech souborů na disku C a podřízený požadavek je vytvořen pro FileIOPermission pro čtení souborů v C:\Temp, tak kontrolní výraz by mohl ovlivnit procházení zásobníku; ale pokud byl požadavek na FileIOPermission pro zápis na disk C, kontrolní výraz by neměl mít žádný vliv.
Aby mohly být výrazy provedeny, váš kód musí mít uděleno jak oprávnění, které uplatňujete tak i SecurityPermission, které představuje právo tvořit výrazy. Ačkoli byste mohli uplatňovat oprávnění, které nebylo uděleno vašemu kódu, kontrolní výraz by byl zbytečný, protože kontrola zabezpečení by selhala předtím, než by výraz mohl způsobit jeho úspěšné uplatnění.
Následující ilustrace ukazuje, co se stane, když použijete metodu Assert. Předpokládejme, že následující příkazy jsou pravdivé u sestavení A, B, C, E a F a dvou oprávnění P1 a P1A:
P1A představuje právo pro čtení .txt souborů na disku C.
P1 představuje právo pro čtení všech souborů na disku C.
P1A a P1 jsou obě typu FileIOPermission a P1A je podmnožinou P1.
Sestavením E a F bylo uděleno oprávnění P1A.
Sestavení C bylo uděleno oprávnění P1.
Sestavením A a B, nebylo uděleno ani oprávnění P1 ani P1A.
Metoda A je obsažena v sestavení A, metoda B je obsažena v sestavení B atd.
Používání metody Assert
V tomto scénáři metoda A volá B, B volá C, C volá E a E volá F. Metoda C uplatňuje oprávnění pro čtení souborů na disku C (oprávnění P1) a metoda E požaduje oprávnění ke čtení txt souborů na disku C (oprávnění P1A). Když je za běhu v metodě F objeven požadavek, je provedeno procházení zásobníku, aby se zkontrolovaly oprávnění všech volajících metody F, počínaje E. Metodě E bylo uděleno oprávnění P1A, takže procházení zásobníku pokračuje zkoumáním oprávnění metody C, kde je objeven kontrolní výraz. Protože požadované oprávnění (P1A) je podmnožinou uplatňovaného oprávnění (P1), procházení zásobníku se zastaví a kontrola zabezpečení automaticky uspěje. Nezáleží na tom, že sestavením A a B nebylo uděleno oprávnění P1A. Metoda C pomocí uplatňování P1 zajišťuje, že její volající mohou přistupovat k prostředku, který je chráněn oprávněním P1, dokonce i když volajícím nebylo uděleno oprávnění pro přístup k tomuto prostředku.
Pokud navrhujete knihovnu tříd a třída přistupuje k chráněnému prostředku, ve většině případů byste měli vytvořit security demand, který vyžaduje, aby volající třídy měli příslušné oprávnění. Pokud třída potom provádí operaci, u které víte, že většina volajících nebude mít oprávnění a pokud jste ochotni převzít odpovědnost za to, že umožníte těmto volajícím volat váš kód, můžete uplatnit oprávnění voláním metody Assert na objekt oprávnění, který představuje operaci, kterou provádí kód. Použití metody Assert tímto způsobem umožňuje volajícím volat váš kód, což by za normálních okolností nemohli. Proto pokud uplatňujete oprávnění, měli byste předem provést vhodné kontroly zabezpečení, aby jste ochránili vaše komponenty před zneužitím.
Předpokládejme například, že vaše vysoce důvěryhodná knihovna tříd má metodu, která odstraňuje soubory. Přistupuje k souborům voláním nespravované Win32 funkce. Volající spustí metodu Delete vašeho kódu předáním názvu souboru, který má být odstraněn (C:\Test.txt). V rámci metody Delete váš kód vytvoří objekt FileIOPermission představující přístup pro zápis do souboru C:\Test.txt. (Přístup pro zápis je vyžadován k odstranění souboru.) Váš kód poté vyvolá imperativní kontrolu zabezpečení voláním metody Demand náležící objektu FileIOPermission. Pokud jeden z volajících v zásobníku volání nemá toto oprávnění, je vyvolána výjimka SecurityException. Pokud není vyvolána žádná výjimka, víte, že všichni volající mají právo přistupovat k souboru C:\Test.txt. Protože jste přesvědčeni, že většina z vašich volajících nebude mít oprávnění pro přístup k nespravovanému kódu, váš kód poté vytvoří objekt SecurityPermission, který reprezentuje právo pro volání nespravovaného kódu a volání metody Assert. Nakonec volá nespravovanou Win32 funkci pro odstranění souboru C:\Text.txt a vrátí řízení volajícímu.
Upozornění |
---|
Musíte si být jisti, že váš kód nepoužívá výrazy v situacích, kde může být použit jiným kódem pro přístup k prostředku, který je chráněn oprávněním, které uplatňujete.Například v kódu, který zapisuje do souboru jehož název je určen volajícím jako parametr, byste neměli uplatnit FileIOPermission pro zápis do souborů, protože váš kód by mohl být otevřen pro zneužití třetí stranou. |
Při použití imperativní syntaxe zabezpečení způsobí volání metody Assert na více oprávnění ve stejné metodě vyvolání výjimky zabezpečení. Místo toho byste měli vytvořit objekt PermissionSet, předat mu jednotlivá oprávnění, která chcete vyvolat a poté na objekt PermissionSet zavolat metodu Assert. Metodu Assert můžete volat více než jednou, pokud použijete deklarativní syntaxi zabezpečení.
Následující příklad ukazuje deklarativní syntaxi pro přepsání kontroly zabezpečení pomocí metody Assert. Všimněte si, že syntaxe FileIOPermissionAttribute má dvě hodnoty: výčet SecurityAction a umístění souboru nebo adresáře, kterému mají být udělena oprávnění. Volání Assert způsobí, že požadavky pro přístup k souboru C:\Log.txt proběhnou úspěšně, přestože volající nejsou zkontrolováni, zda mají oprávnění pro přístupu k souboru.
[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();
}
}
}
Následující fragmenty kódu ukazují imperativní syntaxi pro přepsání kontroly zabezpečení pomocí metody Assert. V tomto příkladě je deklarována instance objektu FileIOPermission. Jeho konstruktoru je předán FileIOPermissionAccess.AllAccess, aby definoval typ povoleného přístupu. Následován je řetězcem, který popisuje umístění souboru. Jakmile je jednou definován objekt FileIOPermission, musíte pouze volat jeho metodu Assert pro přepsání kontroly zabezpečení.
[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();
}
}
}
Viz také
Odkaz
Koncepty
Rozšíření metadat pomocí atributů