Включите Java SecurityManager с помощью AllPermission

Я пытаюсь ознакомиться с SecurityManager но даже этот простой сценарий терпит неудачу. Когда я запускаю следующее изнутри своей IDE или из командной строки, я получаю следующее исключение;

access denied ("java.util.PropertyPermission" "java.home" "read")

Я думал, что позволил все с этим кодом:

Policy.setPolicy(new Policy() {

    @Override
    public PermissionCollection getPermissions(CodeSource codesource) {
        Permissions perm = new Permissions();
        perm.add(new AllPermission());
        return perm;
    }
});
System.setSecurityManager(new SecurityManager());
System.out.println(System.getProperty("java.home"));

Имеет ли это какое-то отношение к политике, производной от JVM? Как я могу чисто setPolicy()?

Такое же недоразумение, кажется, имеет место для следующего кода:

System.setSecurityManager(new SecurityManager());
final Permissions allPermission = new Permissions();
allPermission.add(new AllPermission());
AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
    System.out.println(System.getProperty("java.home"));
    return null;
}, new AccessControlContext(new ProtectionDomain[]{new ProtectionDomain(null, allPermission)}));

Обновление: второй случай понятен, поскольку предоставленное разрешение является лишь дополнительным ограничением: (javadoc) Действие выполняется с пересечением разрешений, которыми обладает домен защиты вызывающего абонента, и разрешений, которыми обладают домены, представленные указанным AccessControlContext

Ответ 1

Я смог воссоздать ваше дело с помощью дополнительного Policy.getPolicy() перед Policy.setPolicy(), причина, по которой это влияет на поведение, заключается в том, что при вызове get policy вы запускаете создание политики по умолчанию и разрешения из java.policy установлены, но без setSecurityManager() они не активируются, поэтому, когда вы делаете настраиваемый набор AllPermission, вы все равно получаете "java.util.PropertyPermission" "java.home" "read", для многих из таких политик по умолчанию не переопределяются с установленной политикой. Действительно очень запутанная структура.

Policy.getPolicy();
Policy.setPolicy(policyWithAllPermission);
System.setSecurityManager(new SecurityManager());
System.out.println(System.getProperty("java.home"));
// results in 'access denied ("java.util.PropertyPermission" "java.home" "read")'

Но если вы используете следующую пользовательскую политику;

Policy allPermissionPolicy = new Policy() {

    @Override
    public boolean implies(ProtectionDomain domain, Permission permission) {
        return true;
    }
};

Он переопределяет все определения разрешений и позволяет всем действиям исправить возможную путаницу.

Ответ 2

В каком контексте вы запускаете свой код выше?

из командной строки с простой JVM или внутри веб-приложения, запущенного поверх какого-то контейнера JavaEE? На какой ОС? с какой JVM (Oracle, OpenJDK, IBM J9...) и какой версией?

Если вы работаете из командной строки, взгляните на файл java.policy расположенный в вашем пути установки JVM. Его содержание может сузить ваши гранты и, следовательно, помешать вам получить доступ к этой конкретной системной переменной?