Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Отражение позволяет получать сведения о типах и членах, а также получать доступ к элементам (то есть вызывать методы и конструкторы, получать и задавать значения свойств, добавлять и удалять обработчики событий и т. д.). Использование рефлексии для получения сведений о типах и участниках не ограничено. Весь код может использовать отражение для выполнения следующих задач:
- Перечисляйте типы и члены и просматривайте их метаданные.
- Перечисление и проверка сборок и модулей.
При использовании рефлексии для доступа к членам, напротив, действуют ограничения. Начиная с .NET Framework 4, только доверенный код может использовать отражение для доступа к критически важным элементам безопасности. Кроме того, только доверенный код может использовать рефлексию для доступа к непубличным членам, которые не являются напрямую доступными для скомпилированного кода. Наконец, код, использующий отражение для доступа к безопасному критическому элементу, должен иметь все разрешения, необходимые для безопасных критически важных элементов, так же, как и в скомпилированном коде.
При условии необходимых разрешений код может использовать отражение для выполнения следующих видов доступа:
Доступ к публичным членам, которые не критичны для безопасности.
Доступ к неопубликованным членам, которые будут доступны для скомпилированного кода, если эти члены не являются критически важными для безопасности. Примеры таких непубличных членов:
Защищенные члены базовых классов вызывающего кода. (В контексте размышлений это называется доступом семейного уровня.)
internal
членов (в Visual Basic -Friend
членов) в сборке вызывающего кода. (В рефлексии это называется доступом на уровне сборки.)Приватные члены других экземпляров класса, в котором содержится вызывающий код.
Например, код, выполняемый в изолированном домене приложения, ограничен доступом, описанным в этом списке, если домен приложения не предоставляет дополнительные разрешения.
Начиная с пакета обновления 1 (SP1) для .NET Framework 2.0, попытка получить доступ к членам, которые обычно недоступны, создает запрос на набор разрешений целевого объекта плюс ReflectionPermission с флагом ReflectionPermissionFlag.MemberAccess. Код, выполняющийся с полным доверием (например, код в приложении, запущенном из командной строки), всегда может удовлетворить эти разрешения. (Это касается ограничений доступа к критически важным элементам безопасности, как описано далее в этой статье.)
При необходимости песочница доменного приложения может предоставить ReflectionPermission с использованием флага ReflectionPermissionFlag.MemberAccess, как описано в разделе Доступ к членам, которые обычно недоступны, в дальнейшей части статьи.
Доступ к элементам Security-Critical
Элемент характеризуется критической безопасностью, если он имеет SecurityCriticalAttribute, принадлежит типу с SecurityCriticalAttribute, или находится в критической сборке безопасности. Начиная с .NET Framework 4, правила доступа к критически важным элементам безопасности приведены следующим образом:
Прозрачный код не может использовать отражение для доступа к критически важным элементам безопасности, даже если код полностью доверенный. MethodAccessException FieldAccessException Или TypeAccessExceptionвызывается.
Код, работающий с частичным доверием, рассматривается как прозрачный.
Эти правила одинаковы независимо от того, осуществляется доступ к критически важному для безопасности члену напрямую с помощью скомпилированного кода или через отражение.
Код приложения, выполняемый из командной строки, выполняется с полным доверием. Если он не помечен как прозрачный, он может использовать отражение для доступа к критически важным элементам безопасности. Если тот же код выполняется с частичным доверием (например, в изолированном домене приложения) уровень доверия сборки определяет, может ли он получить доступ к критическому коду безопасности: если сборка имеет строгое имя и установлена в глобальном кэше сборок, это надежная сборка и может вызывать критически важные для безопасности элементы. Если объект не является доверенным, он становится прозрачным, даже если не помечен как прозрачный, и не может получить доступ к элементам, критически важным для безопасности.
Отражение и прозрачность
Начиная с .NET Framework 4, общеязыковая среда выполнения определяет уровень прозрачности типа или элемента на основе нескольких факторов, включая уровень доверия сборки и уровень доверия домена приложения. Отражение предоставляет свойства IsSecurityCritical, IsSecuritySafeCritical и IsSecurityTransparent, позволяющие обнаруживать уровень прозрачности типа. В следующей таблице показаны допустимые сочетания этих свойств.
Уровень безопасности | IsSecurityCritical | IsSecuritySafeCritical | IsSecurityTransparent |
---|---|---|---|
Критически важно | true |
false |
false |
Критически безопасное | true |
true |
false |
Прозрачный | false |
false |
true |
Использование этих свойств гораздо проще, чем изучение заметок безопасности сборки и его типов, проверки текущего уровня доверия и попытки дублировать правила среды выполнения. Например, тот же тип может быть критически важным для безопасности при запуске из командной строки или не влияющим на безопасность при запуске в изолированном домене приложения.
Существуют аналогичные свойства для классов MethodBase, FieldInfo, TypeBuilder, MethodBuilder и DynamicMethod. (Для других абстракций отражения и эмиссии отражения, атрибуты безопасности применяются к связанным методам; например, в случае свойств, атрибуты применяются к средствам доступа к свойствам.)
Доступ к членам, которые обычно недоступны
Чтобы использовать механизм отражения для вызова членов, недоступных в соответствии с правилами доступности общего языка выполнения, вашему коду должны быть предоставлены одни из двух разрешений:
Чтобы разрешить коду вызывать любой непубличный элемент: вашему коду должен быть предоставлен ReflectionPermission с флагом ReflectionPermissionFlag.MemberAccess.
Замечание
По умолчанию политика безопасности запрещает это разрешение на код, исходящий из Интернета. Это разрешение никогда не должно быть предоставлено коду, созданному из Интернета.
Чтобы разрешить коду вызывать любой непубличный член, если набор разрешений сборки, содержащей вызываемый член, совпадает с набором разрешений сборки, содержащей вызывающий код: вашему коду должен быть предоставлен ReflectionPermission с флагом ReflectionPermissionFlag.RestrictedMemberAccess.
Например, предположим, что вы предоставляете домену приложения разрешения в Интернете плюс ReflectionPermission с ReflectionPermissionFlag.RestrictedMemberAccess флагом, а затем запускаете интернет-приложение с двумя сборками, A и B.
Сборка A может использовать рефлексию для доступа к частным членам сборки B, так как набор разрешений сборки B не включает разрешения, которые не предоставлены A.
Сборка A не может использовать отражение для доступа к закрытым членам сборок .NET Framework, таких как mscorlib.dll, поскольку mscorlib.dll имеет статус полностью доверенного и, следовательно, обладает разрешениями, которые не предоставлены сборке A. Исключение MemberAccessException возникает, когда безопасность доступа к коду выполняет обход стека во время выполнения.
Сериализация
Для сериализации с помощью SecurityPermission флаг SecurityPermissionAttribute.SerializationFormatter предоставляет возможность получать и задавать члены сериализуемых типов независимо от их доступности. Это разрешение позволяет коду обнаруживать и изменять частное состояние экземпляра. (Помимо предоставления соответствующих разрешений тип должен быть помечен как сериализуемый в метаданных.)
Параметры метода с типом MethodInfo
Избегайте написания общедоступных элементов, которые принимают MethodInfo параметры, особенно для доверенного кода. Такие члены могут быть более уязвимыми к вредоносному коду. Например, рассмотрим общедоступный член в высоконадежном коде, принимающий параметр MethodInfo. Предположим, что публичный элемент косвенно вызывает Invoke метод на указанном параметре. Если общедоступный член не выполняет необходимые проверки разрешений, вызов метода Invoke всегда будет успешным, так как система безопасности определяет, что вызывающий объект является высоконадежным. Даже если вредоносный код не имеет разрешения на непосредственное вызов метода, он по-прежнему может сделать это косвенно путем вызова общедоступного члена.
Сведения о версиях
Начиная с .NET Framework 4 прозрачный код не может использовать отражение для доступа к критически важным элементам безопасности.
Флаг ReflectionPermissionFlag.RestrictedMemberAccess представлен в пакете обновления 1 для .NET Framework 2.0. Более ранние версии .NET Framework требуют ReflectionPermissionFlag.MemberAccess флага для кода, использующего отражение для доступа к неопубликованным членам. Это разрешение, которое никогда не должно предоставляться частично доверенному коду.
Начиная с .NET Framework 2.0, использование отражения для получения сведений о неопубликованных типах и членах не требует каких-либо разрешений. В более ранних версиях требуется ReflectionPermission с флагом ReflectionPermissionFlag.TypeInformation.