Когда следует использовать AccessController.doPrivileged()?

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

Это поднимает вопрос: когда следует AccessController.doPrivileged() использоваться? Когда недоверенному коду разрешается вызывать привилегированный код через промежуточные методы? Когда это должно потерпеть неудачу?

Следуя своим рассуждениям, объясните, почему всегда следует разрешать создание ClassLoader: http://findbugs.sourceforge.net/bugDescriptions.html

4 ответа

Решение

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

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

Когда подключаемый модуль вызывает службу, вы выполняете пользовательские проверки безопасности ("имеет ли подключаемый модуль X разрешение на использование этой службы"). Но самому сервису может потребоваться некоторое разрешение ядра Java (чтение системного свойства, запись в файл и т. Д.). Код, который требует эти разрешения, обернут в doPrivileged() так что недостаточные разрешения от ненадежных подключаемых модулей эффективно игнорируются - применяются только привилегии вашего модуля доверенных служб.

  1. ... через промежуточный метод, который имеет разрешения. Нет, последнее действующее разрешение - это пересечение всех разрешений в стеке домена. Итак, предположим, что для выполнения операции требуется разрешение B, а некоторые промежуточные LIB имеют два разрешения B и A. Теперь, когда какой-то ненадежный код с единственным разрешением A вызывает LIB, эффективный набор разрешений (A intersect (A+B)) = A, Следовательно, недоверенный код не может использовать промежуточную LIB для получения дополнительных разрешений.

  2. Когда следует использовать doPriveleged?-> В Java существует множество операций, для которых требуется, чтобы домен вызывающей стороны имел определенные разрешения для успешного выполнения этих операций. System.getProperty является одной из таких операций. Все операции с файлами также требуют специальных разрешений. Когда вы используете AccessController.doPrivileged для вызова этих операций, операция выполняется со всеми правами (разрешениями) вашего домена защиты. Следовательно, если у вашего кода достаточно прав только тогда, он может выполнить эти операции.

По сути, AccessController.doPriviledged() является эквивалентом файла set-user-id. Он говорит: "Настоящим я прошу, чтобы этот метод был выполнен с моими привилегиями, даже если меня вызвал метод, у которого их нет".

Проверьте эти ссылки и прокрутите вниз, чтобы использовать API doPrivileged.

Java 6: http://docs.oracle.com/javase/6/docs/technotes/guides/security/doprivileged.html

Java 7: http://docs.oracle.com/javase/7/docs/technotes/guides/security/doprivileged.html

Когда метод AccessController checkPermission вызывается самой последней вызывающей стороной, основной алгоритм для принятия решения о том, разрешить или запретить запрашиваемый доступ, заключается в следующем:

Если код для любого вызывающего абонента в цепочке вызовов не имеет запрошенного разрешения, возникает исключение AccessControlException, если не выполняется следующее условие - вызывающий абонент, чей код предоставлен, указанное разрешение помечен как "привилегированный" (см. Ниже), и все стороны впоследствии вызываемый этим абонентом (прямо или косвенно) все имеют указанное разрешение

Другие вопросы по тегам