Отключить отражение Java для текущего потока
Мне нужно вызвать некоторый полунадежный Java-код и вы хотите отключить возможность использования отражения в течение всего времени выполнения этого кода.
try{
// disable reflection somehow
someObject.method();
}
finally{
// enable reflection again
}
Можно ли это сделать с помощью SecurityManager, и если да, то как?
Разъяснение/Контекст: Это следующий вопрос другого вопроса об ограничении пакетов, которые можно вызывать из JavaScript/Rhino. Принятый ответ ссылается на запись в блоге о том, как это сделать, и для этого требуется два шага, первый из которых использует Rhino API (ClassShutter), второй - отключение отражения и Class.forName(). Я думал, что могу сделать этот второй шаг более чистым, используя SecurityManager (узнав о SecurityManager, который, как было указано, является сложным зверьком, на этом пути).
Подводя итог, я хочу (из кода, а не устанавливать файл) отключить Class.forName() и любой доступ ко всему пакету отражения.
Ответы
Ответ 1
Это зависит от того, что вы пытаетесь ограничить.
В общем, общедоступный API не ограничен. Однако до тех пор, пока вы не предоставите ненадежный код ReflectPermission("suppressAccessChecks")
, он не сможет получить доступ к не- открытый API в другом пакете.
Если у вас есть список пакетов, для которых вы хотите ограничить доступ, есть два шага. Во-первых, в свойствах Security
включает ограниченный пакет в списке package.access
. Затем введите свой надежный код RuntimePermission("accessClassInPackage." + pkg)
.
Обычный способ отличить ваш ненадежный код - загрузить его из другого места и ссылаться на различные кодовые базы в файле политики при предоставлении разрешений.
Архитектура безопасности Java очень мощная, но я знаю, что она также сложна; если вы хотите более конкретный пример, пожалуйста, опишите, какие именно вызовы вы хотите ограничить, и я попытаюсь быть более явным.
Сделать то, что вы хотите, без изменения файла java.policy
и/или файла java.security
было бы очень сложно, возможно, невозможно. java.security.Policy
представляет информацию в java.policy
, но не предоставляет доступ на запись. Вы можете создать свою собственную реализацию Policy
и установить ее во время выполнения, если это разрешит любой существующий SecurityManager
.
С другой стороны, вы можете указать пользовательский файл java.policy в качестве параметра командной строки. Если вы предоставляете полное приложение с помощью своего рода пусковой установки, это может быть легко выполнено. Он также обеспечивает определенную прозрачность для ваших пользователей. Изощренный пользователь может просмотреть разрешения, которые вы хотели бы предоставить приложению.
Ответ 2
Ну, вы можете переопределить SecurityManager.checkMemberAccess
и дать более строгие определения. Однако на самом деле это не так. Что происходит, например, если код определяет финализатор?
В пояснении: другие API используют рефлексию и другие API. Например, java.beans, LiveConnect и Rhino. Противник мог бы в рамках script, скажем, создать новый контекст Rhino без затвора и, таким образом, загрузить в полную JRE. С открытой системой черный список никогда не может быть завершен.
В заключение: для использования модели безопасности Java вам необходимо работать с ней, а не против нее.
Ответ 3
Я написал замену ClassShutter, которая позволяет осуществлять мелкозернистый контроль доступа на каждый экземпляр для каждого метода за поле:
http://riven8192.blogspot.com/2010/07/java-rhino-fine-grained-classshutter.html