Разрушает ли рефлексия идею частных методов, потому что частные методы могут быть доступны вне класса? - PullRequest
27 голосов
/ 21 июля 2010

Разрушает ли рефлексия идею частных методов? Потому что частные методы могут быть доступны извне класса? (Может быть, я не понимаю смысл отражения или пропустить что-то еще, пожалуйста, скажите мне) http://en.wikipedia.org/wiki/Reflection_%28computer_science%29

Edit: Если перебор нарушает идею частных методов - используем ли мы частные методы только для логики программы, а не для безопасности программы?

Спасибо

Ответы [ 14 ]

26 голосов
/ 22 июля 2010

мы используем частные методы только для логики программы, а не для безопасности программы?

Непонятно, что вы подразумеваете под "безопасностью программы". Безопасность нельзя обсуждать в вакууме; Какие ресурсы вы думаете защищать от каких угроз?

Система защиты доступа к коду CLR предназначена для защиты ресурсов пользовательских данных от угрозы враждебного частично доверенного кода, работающего на компьютере пользователя .

Следовательно, связь между отражением, контролем доступа и безопасностью в CLR является сложной. Вкратце и не совсем точно, правила таковы:

  • полное доверие означает полное доверие. Полностью доверенный код может получить доступ к каждому биту памяти в процессе. Сюда входят приватные поля.

  • Способность размышлять о рядовых в частичном доверительном управлении контролируется разрешением; если он не предоставлен, то код частичного доверия может не отражаться на рядовых.

Подробнее см. http://blogs.msdn.com/b/shawnfa/archive/2006/09/29/777047.aspx.

  • Настольный CLR поддерживает режим, называемый «видимость с ограниченным пропуском», в котором правила взаимодействия отражения и системы безопасности немного отличаются. В принципе, частично доверенный код, который имеет право использовать частное отражение, может получить доступ к частному полю через отражение, если частично доверенный код обращается к частному полю из типа, полученного из сборки с равным или меньше доверие.

См

http://blogs.msdn.com/b/shawnfa/archive/2006/10/05/using-lightweight-codegen-from-partial-trust.aspx

для деталей

Исполнительное резюме таково: вы можете заблокировать частично доверенный код настолько, чтобы он не мог использовать рефлексию для просмотра личных вещей. Вы не можете заблокировать полный код доверия; Вот почему это называется «полное доверие». Если вы хотите ограничить это, тогда не доверяйте этому .

Итак: защищает ли частное поле от угрозы кода с низким уровнем доверия, пытающегося прочитать его и тем самым похитить данные пользователя? Да . Защищает ли он его от угрозы высокого доверия кода, читающего его? Нет . Если код доверен пользователю и враждебен пользователю , то у пользователя возникает большая проблема . Они не должны были доверять этому коду.

Обратите внимание, что, например, закрытие поля не защищает секрет вашего кода от пользователя, который имеет ваш код и враждебен вам . Система безопасности защищает добрых пользователей от злого кода . Он не защищает хороший код от злых пользователей . Если вы хотите сделать что-то личное, чтобы скрыть это от пользователя , тогда вы идете по дураку. Если вы хотите сохранить секретность от злых хакеров, которые заманили пользователя к запуску враждебного кода с низким уровнем доверия , тогда это хороший метод.

19 голосов
/ 21 июля 2010

Reflection действительно позволяет обойти модификаторы защиты доступа Java и поэтому нарушает строгую инкапсуляцию , как это реализовано в C ++ и Java.Однако это не так важно, как вы думаете.

Модификаторы защиты доступа предназначены для того, чтобы помочь программистам разрабатывать модульные, хорошо продуманные системы, а не быть бескомпромиссными хранителями ворот.Иногда есть очень веские причины нарушить строгую инкапсуляцию, такую ​​как Модульное тестирование и разработка фреймворка .

Хотя изначально может быть трудно понять идею о том, что модификаторы защиты доступаих легко обойти, попробуйте помнить, что есть много языков ( Python , Ruby и т. д.), которые вообще не имеют их.Эти языки используются для создания больших и сложных систем, точно так же как языки, которые обеспечивают защиту доступа.

Есть некоторые споры о том, являются ли модификаторы защиты доступа помощью или помехой.Даже если вы цените защиту доступа, относитесь к ней как к руке помощи, а не к созданию или разрушению вашего проекта.

13 голосов
/ 21 июля 2010

Да, но это не проблема.

Инкапсуляция - это не безопасность или секреты, а просто организация вещей.

Отражение не является частью «нормального» программирования.Если вы хотите использовать его, чтобы нарушить инкапсуляцию, вы принимаете на себя риски (проблемы с версиями и т. Д.)

Отражение следует использовать только тогда, когда нет более совершенных (менее инвазивных) способов достижения чего-либо.

Отражение предназначено для системного «инструментария», такого как отображение постоянства, и должно быть спрятано в хорошо протестированных библиотеках.Я нашел бы любое использование отражения в нормальном коде приложения подозреваемым.

Я начал с "это не проблема".Я имел в виду: пока вы используете отражение, как задумано.И осторожнее.

8 голосов
/ 21 июля 2010

Нет, рефлексия не нарушает идею частных методов.По крайней мере, не по сути.Ничто не говорит о том, что отражение не может подчиняться ограничениям доступа.

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

Что я подразумеваю под плохо разработанным ?Ну, как я уже говорил выше, ничто не мешает вам иметь язык, на котором рефлексия подчиняется ограничениям доступа.Проблема заключается в том, что, например, отладчикам, профилировщикам, инструментам покрытия, IntelliSense, IDE, инструментам в целом требуется , чтобы иметь возможность нарушать ограничения доступа.Поскольку невозможно представить разные версии отражения разным клиентам, большинство языков предпочитают инструменты безопасности.(Е является контрпримером, который не имеет абсолютно никаких отражающих способностей, как осознанный выбор дизайна.)

Но кто говорит, что вы не можете представить разные версии отражения разным клиентам?Проблема в том, что в классической реализации отражения все объекты отвечают за отражение самих себя, и поскольку существует только один из каждого объекта, может существовать только версия отражения.

Итак, гдеприходит идея плохой дизайн ?Хорошо, обратите внимание на слово «ответственный» в вышеприведенном абзаце.Каждый объект отвечает за размышления о себе.Кроме того, каждый объект отвечает за то, для чего он был написан в первую очередь.Другими словами: каждый объект имеет как минимум две обязанностей.Это нарушает один из основных принципов объектно-ориентированного проектирования: принцип единой ответственности.

Решение довольно простое: разбить объект.Оригинальный объект просто отвечает за то, для чего он был изначально написан.И есть еще один объект (называемый Mirror , потому что это объект, который отражает другие объекты), который отвечает за отражение.И теперь, когда ответственность за отражение разбита на отдельный объект, что мешает нам иметь не один, а два, три, много Зеркальных объектов?Тот, который учитывает ограничения доступа, тот, который позволяет объекту отражать только себя, но не любые другие объекты, тот, который допускает только самоанализ (то есть только для чтения), тот, который позволяет отражать только информацию о месте вызова только для чтения (то есть дляпрофилировщик), который дает полный доступ ко всей системе, включая нарушение ограничений доступа (для отладчика), тот, который предоставляет доступ только для чтения к именам и сигнатурам методов и соблюдает ограничения доступа (для IntelliSense) и т. д.

В качестве приятного бонуса это означает, что зеркала - это, по сути, возможности (в смысле слова «возможности-безопасность») для отражения.IOW: Зеркала - это Святой Грааль в десятилетнем стремлении согласовать безопасность и динамическое метапрограммирование во время выполнения.

Концепция зеркал была изобретена в Self , откуда она перешла в Animorphic Smalltalk / Strongtalk , а затем Newspeak .Интересно, что интерфейс отладки Java основан на зеркалах, поэтому разработчики Java (или, скорее, JVM) ясно знали о них, но отражение Java не работает.

8 голосов
/ 21 июля 2010

Это как твой дом.Блокировки только защищают честных людей или тех, кто не желает взломать вашу блокировку.

Данные - это данные, если кто-то достаточно решителен, он может делать с вашим кодом все что угодноБуквально что угодно.

Так что да, рефлексия позволит людям делать то, что вы не хотите, чтобы они делали с вашим кодом, например, получать доступ к закрытым полям и методам.Тем не менее, важно то, что люди не будут делать это случайно.Если они используют рефлексию, они знают, что делают то, что, вероятно, не предназначены, точно так же, как никто случайно не взломает замок на вашей входной двери.

5 голосов
/ 21 июля 2010

Это так, как другие уже заявили.

Однако я помню, что в Java может быть активным менеджер безопасности, который может помешать вам получить доступ к любым закрытым методам, даже с отражением, если у вас нет прав на это. Если вы используете локальную JVM, такой менеджер обычно не активен.

4 голосов
/ 21 июля 2010

Да, это нарушает инкапсуляцию, если вы этого хотите. Тем не менее, это может быть полезно - например, написание модульных тестов для частных методов, или иногда - как я узнал из собственного опыта - для устранения ошибок в сторонних API:

Обратите внимание, что инкапсуляция! = Безопасность. Инкапсуляция - это объектно-ориентированная концепция дизайна, предназначенная только для улучшения дизайна. Для безопасности в java есть SecurityManager .

4 голосов
/ 21 июля 2010

Да, Reflection может использоваться для нарушения инкапсуляции и даже для неправильного поведения. Имейте в виду, что сборке необходимо доверять для выполнения отражения, поэтому все еще существуют некоторые средства защиты.

4 голосов
/ 21 июля 2010

Да, рефлексия разрушает эту идею. В родных языках также есть некоторые приемы, позволяющие нарушать правила ООП, например, в C ++ можно изменять закрытые члены класса, используя приемы указателей. Однако, используя эти приемы, мы получаем код, который может быть несовместим с будущими версиями классов - это цена, которую мы платим за нарушение правил ООП.

2 голосов
/ 21 июля 2010

Да, это нарушает инкапсуляцию. Но есть много веских причин использовать его в некоторых ситуациях.

Например:

Я использую MSCaptcha на некоторых веб-сайтах, но он отображает

вокруг тега image, который мешает моему HTML. Затем я могу использовать стандартный тег imageи использовать отражение, чтобы получить значение идентификатора изображения капчи для создания URL.

Идентификатор изображения является частной собственностью, но используя отражение, я могу получить это значение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...