Использование метода Deny

Важное примечаниеВажно

В версии .NET Framework 4 удалена поддержка среды выполнения для принудительного применения запросов разрешений Deny, RequestMinimum, RequestOptional и RequestRefuse.Эти запросы нельзя использовать в коде, основанном на .NET Framework 4 или более поздних версиях.Дополнительные сведения об этом и других изменениях см. в разделе Изменения системы безопасности в платформе .NET Framework 4.

Вызов Deny запрещает доступ к ресурсу, указанному в отклоняемом разрешении. Если код вызывает метод Deny и вызываемый объект впоследствии затребует отвергнутое разрешение, проверка безопасности потерпит неудачу, даже если все вызывающие объекты будут иметь разрешение на доступ к этому ресурсу. Затребованное и отклоняемое разрешение не обязаны в точности совпадать для выполнения метода Deny, и затребованное разрешение не обязано быть подмножеством отклоненного. Однако если пересечение этих двух разрешений является пустым множеством (т.е. при отсутствии общих элементов), вызов Deny не принесет никакого результата. Обратите внимание, что метод Deny не может переопределить действия кода, расположенного более глубоко в стеке вызовов и выполняющего метод Assert. Если код, находящийся более глубоко по стеку вызовов, выполняет метод Assert, он может получить доступ к ресурсу, отклоняемый кодом, расположенным выше в стеке вызовов.

Вызовы метода Deny можно использовать в коде для защиты себя от обязательств, так как Deny делает невозможным использование вашего кода для доступа к отвергаемому ресурсу. Тем не менее, вызов Deny не блокирует будущие утверждения безопасности, выполняемые вызываемыми объектами.

Следующая иллюстрация показывает, что происходит при использовании метода Deny. Предположим, что для сборок A, B, C, D и E, а также разрешения P1 верны следующие утверждения:

  • P1 предоставляет право на чтение любых файлов на диске C;

  • сборки A, B, C, D и E обладают разрешением P1;

  • метод F применяет требование к разрешению P1;

  • метод C создает экземпляр класса P1 и затем вызывает его метод Deny;

  • метод A содержится в сборке A, метод B содержится в сборке В и так далее.

Использование метода Deny

Требование и отказ в разрешении

Вызов Deny методом C может повлиять на результат требования P1. Например, предположим, что метод A вызывает B, B вызывает C, C вызывает E, а E вызывает F. Так как метод F напрямую осуществляет доступ к ресурсу, защищаемому P1, метод F инициирует проверку безопасности на P1 путем вызова метода Demand объекта P1. Это требование заставляет среду выполнения проверить разрешения всех вызывающих объектов в стеке вызовов, начиная со сборки E. Так как сборка E имеет разрешение P1, среда выполнения продолжает анализировать разрешения сборки C. Но поскольку метод C отверг P1, проверка безопасности, начатая методом E, терпит неудачу на этом этапе, и создается исключение SecurityException. Не имеет значения, обладают ли сборка C и ее вызывающие объекты (сборки A и B) разрешением P1; проверка безопасности в любом случае потерпит неудачу. Так как метод C вызвал Deny, код в сборках A и B не может получить доступ к ресурсу, защищаемому P1.

Следующий код демонстрирует декларативный синтаксис переопределения проверок безопасности с использованием метода Deny. В данном примере синтаксис ReflectionPermission определяет два значения: перечисление SecurityAction и значение свойства TypeInformation. Свойству TypeInformation присваивается значение "true", чтобы указать, что данное разрешение предоставляет право просматривать закрытые члены посредством отражения, а значение SecurityAction.Deny передается для запрещения этого разрешения. Полный список возможных значений ReflectionPermission см. в описании этого перечисления. При использовании такого объявления безопасности метод не сможет читать закрытые члены типа посредством отражения.

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

Следующий код демонстрирует принудительный синтаксис переопределения проверок безопасности с использованием метода Deny. В этом примере объявляется объект ReflectionPermission, а его конструктору передается значение ReflectionPermissionFlag.TypeInformation для инициализации текущего разрешения. После вызова метода Deny код и любые его вызывающие объекты не смогут использоваться для чтения закрытых полей посредством отражения.

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

Проблемы каноничности при использовании метода Deny

При запрете разрешений FileIOPermission, RegistryPermission, WebPermission, UrlIdentityPermission, SiteIdentityPermission и EnvironmentPermission следует соблюдать особую осторожность, так как отдельные файлы, значения реестра, URL-адреса и системные пути могут описываться с использованием различных имен. Например, на файл MyFile.log можно сослаться несколькими способами, включая "c:\MyFile.log" и "\\MyMachineName\c$\MyFile.log". При создании разрешения, предоставляющего доступ к "c:\\MyFile.txt", и его последующего запрещения для кода, код может все еще иметь возможность осуществлять доступ к этому файлу, используя альтернативный путь "\\\\MyMachineName\\c$\\MyFile.log".

Во избежание проблем каноничности можно использовать сочетания PermitOnly и Deny. PermitOnly дает возможность указать только одно из нескольких возможных имен для ресурса, причем в качестве побочного эффекта запрещается доступ к этому ресурсу с использованием любого другого имени. После использования PermitOnly для указания единственного разрешенного имени для ресурса нужно использовать Deny для отмены доступа к ресурсу по этому имени.

В следующем коде сочетание методов Deny и PermitOnly используется для запрещения доступа со стороны кода к ресурсу с именем MyLog.log. Этот код также блокирует доступ к ресурсу с использованием любых альтернативных имен и путей.

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

См. также

Ссылки

SecurityAction

RegistryPermissionAttribute

Основные понятия

Расширение метаданных с помощью атрибутов

Переопределение результатов проверки безопасности

Управление доступом для кода