Подтвердить что ты не робот

Использование AccessController

Я пытаюсь понять основы безопасности Java и AccessController.doPrivileged() я начал с примера программы

import java.security.AccessController;
import java.security.PrivilegedAction;
public class AccessSystemProperty {
   public static void main(String[] args) {
     System.out.println(System.getSecurityManager());
       AccessController.doPrivileged(
        new PrivilegedAction<Boolean>(){
           public Boolean run(){
               System.out.println(System.getProperty("java.home"));
               return Boolean.TRUE;
           }
        }
       );
   }
}

если я пытаюсь запустить выше код, используя управление безопасностью по умолчанию, я получаю AccessControlException Мой стек состоит из

C:\>java -Djava.security.manager AccessSystemProperty
[email protected]
Exception in thread "main" java.security.AccessControlException: access denied (
java.util.PropertyPermission java.home read)
        at java.security.AccessControlContext.checkPermission(Unknown Source)
        at java.security.AccessController.checkPermission(Unknown Source)
        at java.lang.SecurityManager.checkPermission(Unknown Source)
        at java.lang.SecurityManager.checkPropertyAccess(Unknown Source)
        at java.lang.System.getProperty(Unknown Source)
        at AccessSystemProperty$1.run(AccessSystemProperty.java:9)
        at AccessSystemProperty$1.run(AccessSystemProperty.java:8)
        at java.security.AccessController.doPrivileged(Native Method)
        at AccessSystemProperty.main(AccessSystemProperty.java:6)

Просьба помочь мне получить четкое представление о

1), когда нам нужно использовать AccessController.doPrivileged()?. (если присутствует SecurityManager, мы используем AccessController.doPrivileged, почему это не работает в приведенном выше примере) 2) Какое реальное преимущество мы получаем с помощью AccessController и PrivilegedAction?. 3) Нужен ли нам специальный файл политики для приведенного выше примера? Благодаря, Пол

4b9b3361

Ответ 1

Вы должны использовать AccessController.doPrivileged(), чтобы предоставить определенные права на код, которые ранее были в коде вызывающего стека, но у которых есть привилегированные коды, в силу того, что привилегия предоставляется в политике.

Например, предположим, что ClassA вызывает методы в ClassB, а ClassB должен прочитать системное свойство java.home(заимствовать из вашего примера) и предположить, что вы указали, что SecurityManager присутствует в вашем примере.

Также предположим, что ClassB загружается из jar с именем "classb.jar" (но для того, чтобы сделать пример работы ClassA, НЕ загружается из этого баннера), в файле политики безопасности должно быть указано следующее:

grant codeBase "file:/home/somebody/classb.jar" { 
    permission java.util.PropertyPermission "java.home", "read";
};

Теперь, когда ClassB запускается и пытается сделать System.getProperty(), который НЕ завернут в AccessController.doPrivileged() на "java.home". диспетчер безопасности проверяет стек, чтобы узнать, имеет ли каждый класс выше в стеке свойство PropertyPermission (прямо или косвенно) для "java.home". Если нет, доступ завершится неудачно.

Однако, если ClassB обертывает System.getProperty() в AccessController.doPrivileged(), менеджер безопасности только заботится о том, чтобы файл политики предоставил ClassB эту привилегию, и поэтому доступ разрешен.

Здесь фрагмент, чтобы показать это:

public void doStuff() {

    try {
        /*
         * this will fail even if this class has permission via the policy file
         * IF any caller does not have permission
         */
        System.out.println(System.getProperty("java.home")); 
    } catch (Exception e1) {
        System.out.println(e1.getMessage());
    }
    AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
        public Boolean run() {
            try {
                /*
                 * this will be allowed if this class has permission via the policy
                 * file even if no caller has permission
                 */
                System.out.println(System.getProperty("java.home"));
            } catch (Exception e) {
                System.out.println(e.getMessage());
            }

            return Boolean.TRUE;
        }
    });

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