Utilisation de la méthode Deny

Mise à jour : novembre 2007

L'appel à Deny empêche l'accès à la ressource spécifiée par l'autorisation refusée. Si votre code appelle Deny et si un appelant en aval demande ultérieurement l'autorisation refusée, la vérification de sécurité échouera, même si tous les appelants ont l'autorisation d'accéder à cette ressource. L'autorisation demandée et l'autorisation refusée n'ont pas à correspondre exactement pour que Deny prenne effet et l'autorisation demandée n'a pas à être un sous-ensemble de l'autorisation refusée. Cependant, si l'intersection des deux autorisations est vide (c'est-à-dire si elles n'ont rien en commun), l'appel à Deny n'aura aucun effet. Notez que Deny ne peut pas substituer de code plus profond sur la pile des appels qui effectue un Assert. Si du code plus profond sur la pile des appels effectue un Assert, ce code peut accéder à la ressource que le code plus haut dans la pile des appels refuse.

Vous pouvez utiliser des appels à Deny dans votre code pour vous protéger de toute responsabilité puisque Deny rend l'utilisation de votre code impossible pour accéder à la ressource refusée. L'appel à Deny ne bloque cependant pas les assertions de sécurité futures par des appelants en aval.

L'illustration suivante montre ce qui se passe lorsque vous utilisez Deny. Supposez que les instructions suivantes soient vraies concernant les assemblys A, B, C, D et E et l'autorisation P1 :

  • P1 représente le droit de lire tous les fichiers sur le lecteur C.

  • P1 a été octroyé aux assemblys A, B, C, D et E.

  • La méthode F émet une demande sur l'autorisation P1.

  • La méthode C crée une instance de la classe P1 puis appelle la méthode Deny de P1.

  • La méthode A est contenue dans l'assembly A, la méthode B est contenue dans l'assembly B et ainsi de suite.

Utilisation de Deny

Demande et refus d'autorisation

L'appel de la méthode C à Deny peut affecter le résultat des demandes pour P1. Par exemple, supposons que cette méthode A appelle B, B appelle C, C appelle E et E appelle F. Puisque la méthode F accède directement à la ressource que P1 protège, elle appelle une vérification de sécurité pour P1 en appelant la méthode Demand de P1 (ou en utilisant une demande déclarative). Cette demande conduit le runtime à vérifier les autorisations de tous les appelants dans la pile des appels, en commençant par l'assembly E. Comme l'assembly E a reçu l'autorisation P1, le runtime continue à examiner les autorisations de l'assembly C. Mais puisque la méthode C a refusé P1, la vérification de sécurité appelée par la méthode E échoue à ce stade et l'exception SecurityException est levée. Le fait que P1 ait été octroyée à l'assembly C et à ses appelants (assemblys A et B) n'a pas d'importance ; la vérification de sécurité échoue quand même. Étant donné que la méthode C a appelé Deny, le code des assemblys A et B ne peut pas accéder à la ressource protégée par P1.

Le code suivant illustre la syntaxe déclarative de substitution des vérifications de sécurité à l'aide de la méthode Deny. Dans cet exemple, la syntaxe ReflectionPermission spécifie deux valeurs : une énumération SecurityAction et le paramètre pour la propriété TypeInformation. La valeur true est affectée à TypeInformation pour spécifier que cette autorisation représente l'autorisation d'afficher des membres privés via la fonctionnalité de réflexion et SecurityAction.Deny est passé pour refuser cette autorisation. Consultez la description de ReflectionPermission pour obtenir une liste complète des valeurs que vous pouvez spécifier. Grâce à cette déclaration de sécurité, la méthode ne peut pas lire de membres privés d'un type via la fonctionnalité de réflexion.

using System;
using System.Security.Permissions;

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

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

Le code suivant illustre la syntaxe impérative de substitution des vérifications de sécurité à l'aide de la méthode Deny. Dans cet exemple, l'objet RegistryPermission est déclaré et RegistryPermissionAccess.Write est passé à son constructeur pour initialiser l'autorisation en cours. Lorsque la méthode Deny est appelée, le code et les appelants ne peuvent jamais être utilisés pour lire des champs privés via la fonctionnalité de réflexion.

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.
   }  
}

Vous devez faire très attention lors du refus de FileIOPermission, RegistryPermission, WebPermission, UrlIdentityPermission, SiteIdentityPermission et EnvironmentPermission car les fichiers uniques, les entrées du Registre, les URL et les chemins d'accès du système de fichiers peuvent être décrits à l'aide de plusieurs noms. Par exemple, un fichier unique, MyFile.log, peut être référencé de manières différentes, y compris « c:\MyFile.log » et « \\MyMachineName\c$\MyFile.log ». Si vous créez une autorisation qui représente l'accès à « c:\MyFile.log » puis refuse cette autorisation à votre code, celui-ci peut toujours avoir accès au fichier à l'aide du chemin d'accès de substitution « \\MyMachineName\c$\MyFile.log ».

Vous pouvez utiliser une combinaison de PermitOnly et Deny pour éviter des problèmes de canonisation. PermitOnly vous permet de spécifier uniquement un seul nom parmi plusieurs noms possibles pour une ressource et possède un effet secondaire : celui de refuser l'accès à cette ressource qui utilise n'importe quel autre nom. Après avoir utilisé PermitOnly pour spécifier le seul nom autorisé pour une ressource, vous devez utiliser Deny pour refuser l'accès à la ressource qui utilise ce nom.

Le code suivant utilise une combinaison de Deny et PermitOnly pour empêcher votre code d'accéder à une ressource nommée MyLog.log. Ce code empêche également l'accès à la ressource qui utilise tous les noms ou chemins d'accès de substitution.

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

Ajouts de la communauté

Afficher: