Требования
Обновлен: Ноябрь 2007
Можно использовать вызовы требований безопасности декларативно или принудительно для указания разрешений, которыми должны обладать прямые или непрямые вызывающие объекты для доступа к данной библиотеке. Прямые вызывающие объекты явно вызывают статические методы или методы экземпляров классов вашей библиотеки, в то время как непрямые вызывающие объекты вызывают статические методы или методы экземпляров классов другой библиотеки, которая, в свою очередь, вызывает вашу библиотеку. Когда применяется требование, любое приложение, включающее код, будет выполняться только в том случае, если все прямые и непрямые вызывающие методы имеют разрешения, указанные в требовании. Требования, в частности, используются в тех ситуациях, когда библиотека классов использует защищенные ресурсы, к которым нежелательно предоставлять доступ из ненадежного кода. Требования могут помещаться в код с использованием принудительного или декларативного синтаксиса.
Следует принять во внимание, что большинство классов в .NET Framework уже имеют ассоциированные требования, так что нет необходимости производить дополнительное требование при использовании классов, осуществляющих доступ к защищенному ресурсу. Например, класс StreamWriter автоматически осуществляет требование безопасности для разрешения FileIOPermission, когда открывается. Требование FileIOPermission при использовании StreamWriter приведет к лишней и неэффективной проверке стека. Требования необходимо использовать для защиты пользовательских ресурсов, которым нужны особые разрешения.
Требования могут быть декларативными или принудительными.
Проверки стека
Требования обеспечивают безопасность путем выполнения анализа (называемого проверкой стека), в ходе которого каждая вызывающая функция (или фрейм стека) в текущем стеке вызова проверяется на наличие определенного разрешения. При срабатывании требования происходит следующее.
Проверка стека начинается с фрейма стека вызывающего объекта, а не с текущего стека, где срабатывает требование. Например, если метод А вызывает метод Б, а для метода Б действует требование, проверка стека начинается с фрейма стека метода А. В ходе проверки стека метод Б не анализируется.
Стек вызова проверяется до тех пор, пока не будет достигнута точка входа программы (обычно это метод Main) или пока не будет обнаружен модификатор проверки стека, например метод Assert. Дополнительные сведения о модификаторах проверки стека см. в разделе Переопределение результатов проверки безопасности.
Если требование и модификатор проверки стека (например, Assert), относящиеся к одному разрешению, встречаются в пределах одного фрейма стека, приоритет имеет требование.
Принудительный и декларативный синтаксис ведут себя одинаково.
Обратите внимание, что требование, налагаемое на точку входа программы, не подлежит оценке, поскольку проверка стека всегда начинается с вызывающего фрейма стека, однако в данном случае такой вызывающий кадр отсутствует. Поэтому требования, налагаемые на точку входа программы, всегда удовлетворяются.
Декларативные требования
Декларативные требования помещают информацию в метаданные кода, используя атрибуты. Декларативный синтаксис используется для размещения требования как на уровне классов, так и на уровне методов кода.
Если поместить декларативную проверку безопасности на уровне класса, она применяется ко всем членам класса. Но если поместить декларативную проверку безопасности на уровне члена, она будет относиться только к этому члену и переопределит разрешение, указанное на уровне класса, если таковое существует. Например, представим, что на уровне класса было указано, что требуется разрешение PermissionА, а для метода Method1 этого класса указано, что требуется разрешение PermissionB. Когда будет вызван метод Method1, проверка безопасности будет искать только разрешение PermissionB, в то время как остальные методы класса будут требовать PermissionA.
В следующем примере декларативное требование пользовательского разрешения CustomPermission применяется ко всем вызывающим объектам метода ReadData. Это разрешение — гипотетическое, его не существует в .NET Framework. Это пользовательское разрешение имеет отдельно определенный атрибут CustomPermissionAttribute, выполняющий требование. В данном случае он принимает флаг SecurityAction.Demand, чтобы указать тип требования, которое будет выполнять атрибут.
<CustomPermissionAttribute(SecurityAction.Demand, Unrestricted := True)>Public Shared Function ReadData() As String
'Read from a custom resource.
End Function
[CustomPermissionAttribute(SecurityAction.Demand, Unrestricted = true)]
public static string ReadData()
{
//Read from a custom resource.
}
Принудительные требования
Принудительные требования помещаются на уровне методов кода путем создания нового экземпляра объекта-разрешения и вызова метода Demand этого объекта. Принудительный синтаксис не может использоваться для помещения требований на уровне класса.
Принудительное требование, помещаемое непосредственно в код, надежно защищает весь остальной код метода, в котором был вызван метод Demand. Проверка безопасности происходит при запуске метода Demand; если проверка безопасности терпит неудачу, создается исключение SecurityException, и оставшийся код этого метода или члена не выполняется, если исключение SecurityException не было перехвачено и обработано.
В следующем примере используется явный синтаксис с целью затребовать разрешение CustomPermission от всех вызывающих объектов. Этот код создает новый экземпляр класса CustomPermission, передавая конструктору флаг PermissionState.Unrestricted. Затем вызывается метод Demand.
Public Shared Sub ReadData()
Dim MyPermission As New CustomPermission(PermissionState.Unrestricted)
MyPermission.Demand()
'Read from a custom resource.
End Sub
public static void ReadData()
{
CustomPermission MyPermission = new CustomPermission(PermissionState.Unrestricted);
MyPermission.Demand();
//Read from a custom resource.
}
Примечание. |
---|
Оптимизация выполнения требований для 64-битных и 32-битных платформ производится по-разному. На 64-битных платформах требование не будет проверять набор разрешений, предоставленный сборке, которая содержит требование, в случае отсутствия других вызывающих сборок. Однако подобная оптимизация не приводит к повышению уровня привилегий, поскольку проверка стека выполняется при наличии других вызывающих сборок. На 32-битных платформах требование проверяет набор разрешений, предоставленный сборке, которая содержит требование, и всем вызывающим сборкам. |
См. также
Основные понятия
Создание собственных разрешений доступа к коду
Добавление поддержки декларативной безопасности
Написание безопасных библиотек классов