#java #reflection #securitymanager #policies
#java #отражение #securitymanager #Политики
Вопрос:
Я прочитал довольно много вопросов в Stackoverflow по этому вопросу, но не смог найти решение или ответ на мою проблему. Если оно уже есть, я был бы признателен, если бы кто-нибудь дал подсказку…
Моя проблема / вопрос в том, возможно ли полностью отключить отражение для ненадежного кода? Такие функции, как getDeclaredMethods()
(См. test.java ). У меня уже есть Java Security Manager, который выдает исключения безопасности, если код пытается записать / прочитать / и т.д. …
Если это возможно, может кто-нибудь показать мне, как?
Бруно
test.java
TestClass cls = new TestClass();
Class c = cls.getClass();
// returns the array of Method objects
Method[] m = c.getDeclaredMethods();
for(int i = 0; i < m.length; i ) {
System.out.println("method = " m[i].toString());
}
Ответ №1:
Таким образом, я решил проблему не напрямую с помощью checkPermission (). Мой обходной путь — проверить, доступен ли пакет java.lang.reflect.
@Override
public void checkPackageAccess(String pkg){
// don't allow the use of the reflection package
if(pkg.equals("java.lang.reflect")){
throw new SecurityException("Reflection is not allowed!");
}
}
Комментарии:
1. Возможно, я здесь ошибаюсь, но я совершенно уверен, что
if (pkg.startsWith("java.lang.reflect")){
было бы намного безопаснее.
Ответ №2:
Расширьте свой SecurityManager и попросите его проверить наличие ReflectPermission
и RuntimePermission
. Затем вы должны решить, имеет ли вызывающий абонент разрешение на отражение:
@Override
public void checkPermission(Permission perm) {
if (perm instanceof ReflectPermission) {
// called for Method.setAccessible(true)
// determine whether caller is permitted using getClassContext()
}
if (perm instanceof RuntimePermission) {
if (perm.implies(new RuntimePermission("accessDeclaredMembers"))) {
// called for Class.getDeclardFields()
System.out.println("getDeclaredFields() called");
}
}
Комментарии:
1. Я скопировал ваш код и добавил
throw new SecurityException(...)
но исключение не выдается… функция даже не вызывается …2. Да, это не вызывается для
getDeclaredMethods()
, но если вы хотите получить доступ к частным / защищенным методам черезMethod.setAccessible(true)
SecurityManager
вызывается.3. Я обновил answear для проверки на
getDeclardXYZ()
. Надеюсь, это поможет.4. Это не работает так хорошо, я не знаю почему, но функция checkPermission даже не вызывается…
5. Является ли политика глобальной или вы можете установить ее для определенного пакета? Например, в ситуациях, когда у вас есть плагины, как вы могли бы ограничить только JAR плагина. Потому что возможно, что у нас могут быть другие библиотеки (ORM, Gson и т.д.), Которые зависят от отражения.
Ответ №3:
Пока мы не предоставляем security manager, частные члены класса могут быть доступны. Для доступа к закрытым членам класса вы должны установить значение setAccessible(true), это позволит вам получить доступ к закрытым членам. Чтобы ограничить доступ к закрытым элементам, сохраняйте нижеприведенную строку кода в вашем неизменяемом конструкторе класса.
System.setSecurityManager(новый SecurityManager());
Это вызовет исключение AccessControlException при попытке установить значение setAccessible(true).