Utilizzo del metodo Deny

Aggiornamento: novembre 2007

Chiamando il metodo Deny si impedisce l'accesso alla risorsa specificata dall'autorizzazione negata. Se, dopo che è stato chiamato Deny, un chiamante downstream richiede l'autorizzazione negata, il controllo di protezione ha esito negativo anche qualora tutti i chiamanti dispongano dell'autorizzazione per l'accesso alla risorsa. Perché Deny abbia effetto, non è necessario che l'autorizzazione pretesa e l'autorizzazione negata corrispondano esattamente, né che l'autorizzazione pretesa sia un sottoinsieme dell'autorizzazione negata. Se, però, l'intersezione delle due autorizzazioni è vuota, ossia se non hanno nulla in comune, la chiamata di Deny non avrà effetto. Deny non può eseguire l'override di codice situato più in profondità nello stack di chiamate in cui viene eseguito un metodo Assert. Se nel codice situato più in profondità nello stack di chiamate viene eseguito un metodo Assert, sarà possibile accedere alla risorsa il cui accesso è negato dal codice situato nella parte alta dello stack.

L'utilizzo di chiamate del metodo Deny nel codice consente di proteggere gli sviluppatori da qualunque responsabilità relativa al codice. Il metodo Deny impedisce infatti l'utilizzo del codice per accedere alla risorsa negata. La chiamata di Deny non impedisce tuttavia l'effettuazione di future asserzioni di protezione da parte dei chiamanti downstream.

Nell'illustrazione che segue vengono mostrate le fasi dell'utilizzo del metodo Deny. Si supponga che le seguenti affermazioni siano valide per gli assembly A, B, C, D ed E e per l'autorizzazione P1:

  • P1 rappresenta il diritto di leggere tutti i file contenuti nell'unità C.

  • Agli assembly A, B, C, D ed E è stata concessa l'autorizzazione P1.

  • Il metodo F impone l'autorizzazione P1.

  • Il metodo C crea un'istanza della classe P1 e ne chiama il metodo Deny.

  • Nell'assembly A è contenuto il metodo A, nell'assembly B è contenuto il metodo B e così via.

Utilizzo di Deny

Richiesta e negazione autorizzazione

La chiamata effettuata dal metodo C a Deny può influenzare il risultato delle pretese di P1. Si supponga ad esempio che il metodo A chiami B, B chiami C, C chiami E ed E chiami F. Poiché il metodo F accede direttamente alla risorsa protetta da P1, il metodo F richiama un controllo di protezione per P1 chiamandone il metodo Demand o utilizzando una pretesa dichiarativa. Questa pretesa determina il controllo delle autorizzazioni di tutti i chiamanti nello stack di chiamate da parte del runtime a partire dall'assembly E. Poiché l'assembly E dispone dell'autorizzazione P1, il runtime procede a esaminare le autorizzazioni dell'assembly C. Poiché tuttavia il metodo C ha negato P1, il controllo di sicurezza richiamato dal metodo E si interrompe in questo punto e viene generata un'eccezione SecurityException. Non è rilevante che all'assembly C e ai relativi chiamanti (assembly A e B) sia stata o meno concessa P1: il controllo di protezione ha comunque esito negativo. Poiché il metodo C ha chiamato Deny, il codice contenuto negli assembly A e B non può accedere alla risorsa protetta da P1.

Nell'esempio di codice seguente viene illustrato l'utilizzo della sintassi dichiarativa per eseguire l'override dei controlli di protezione mediante il metodo Deny. In questo esempio, nella sintassi di ReflectionPermission sono specificati due valori: un'enumerazione SecurityAction e l'impostazione della proprietà TypeInformation. La proprietà TypeInformation è impostata su true per specificare che l'autorizzazione rappresenta il diritto di visualizzare membri privati tramite reflection e SecurityAction.Deny viene passato per negare questa autorizzazione. Per esaminare un elenco completo dei valori che è possibile specificare, vedere la descrizione di ReflectionPermission. Questa dichiarazione di protezione consente di impedire che il metodo possa leggere membri privati di un tipo tramite reflection.

Option Strict
Option Explicit
Imports System
Imports System.Security.Permissions
<ReflectionPermissionAttribute(SecurityAction.Deny, TypeInformation = true ")> Public Class 
MyClass1
   Public Sub New()
   End Sub
   Public Sub GetPublicMembers ()
      ' Access public members through reflection.
   End Sub
End Class
using System;
using System.Security.Permissions;

[ReflectionPermissionAttribute(SecurityAction.Deny, TypeInformation = true)]
public class MyClass
{
   public MyClass()
   {    
   }   

   public void GetPublicMembers()
   {
      //Access public members through reflection.
   }  
}

Nel codice seguente viene illustrato l'utilizzo della sintassi imperativa per eseguire l'override dei controlli di protezione mediante il metodo Deny. In questo caso, viene dichiarato l'oggetto ReflectionPermission e ne viene passato il costruttore ReflectionPermissionFlag.TypeInformation per inizializzare l'autorizzazione corrente. Quando viene chiamato il metodo Deny, non è possibile utilizzare né il codice né i chiamanti del codice per leggere i campi privati tramite reflection.

Option Explicit
Option Strict
Imports System
Imports System.Security.Permissions
Public Class MyClass1
   Public Sub New()
   End Sub
   Public Sub ReadRegistry()
      Dim MyPermission As New ReflectionPermission (ReflectionPermissionFlag.TypeInformation)
      MyPermission.Deny()
      ' Access public members through reflection.
   End Sub 
End Class
using System;
using System.Security.Permissions;

public class MyClass {
   public MyClass() {    
   }   

   public void ReadRegistry() { 
      ReflectionPermission MyPermission = new ReflectionPermission (ReflectionPermissionFlag.TypeInformation);
      MyPermission.Deny();

      // Access public members through reflection.
   }  
}

Problemi nell'uso di nomi canonici utilizzando Deny

È necessaria estrema attenzione quando si negano le autorizzazioni FileIOPermission, RegistryPermission, WebPermission, UrlIdentityPermission, SiteIdentityPermission e EnvironmentPermission perché singoli file, voci del Registro di sistema, URL e percorsi di sistema possono essere descritti con più nomi. Il riferimento a un singolo file, MyFile.log, può essere ad esempio "c:\MyFile.log" o "\\MyMachineName\c$\MyFile.log". Se si crea un'autorizzazione che rappresenta l'accesso a "c:\MyFile.log" e quindi si nega tale autorizzazione nel codice, può essere comunque possibile accedere al file tramite il percorso alternativo "\\MyMachineName\c$\MyFile.log".

Per evitare problemi con i nomi canonici è possibile utilizzare una combinazione di PermitOnly e Deny. PermitOnly fornisce la possibilità di specificare solo uno dei nomi possibili per una risorsa, anche se presenta l'effetto collaterale di negare l'accesso a tale risorsa con ogni nome alternativo. Una volta utilizzato PermitOnly per specificare l'unico nome autorizzato ad accedere alla risorsa, utilizzare Deny per impedire l'accesso alla risorsa con questo nome.

Nel codice riportato di seguito viene utilizzata una combinazione di Deny e PermitOnly per impedire l'accesso dal codice a una risorsa denominata MyLog.log. Tramite tale codice è anche possibile bloccare l'accesso utilizzando tutti i nomi o i percorsi alternativi della risorsa.

<FileIOPermissionAttribute(SecurityAction.PermitOnly, All := "C:\ "), FileIOPermissionAttribute(SecurityAction.Deny, All := "C:\MyLog.log")>
[FileIOPermissionAttribute(SecurityAction.PermitOnly, All = @"C:\ ")]
[FileIOPermissionAttribute(SecurityAction.Deny, All = @"C:\MyLog.log")] 

Vedere anche

Concetti

Override dei controlli di protezione

Riferimenti

SecurityAction

RegistryPermissionAttribute

Altre risorse

Estensione di metadati mediante attributi

Protezione dall'accesso di codice