Spec-Zone .ru
спецификации, руководства, описания, API
|
Политика для установки SDK определяет, какие полномочия - какие типы доступов системного ресурса - позволяются для кода из указанных источников кода. "Источник кода" (типа CodeSource) по существу состоит из участка кода (URL) и ссылка на сертификат (ы), содержащий открытый ключ (и), соответствующий закрытому ключу (ам), используемому, чтобы подписать код (если это было подписано).
Политика представляется объектом Политики. Более определенно это представляется a Policy
подкласс, обеспечивающий реализацию абстрактных методов в Policy
класс (который находится в java.security
пакет).
Исходное расположение для информации о политике, используемой объектом Политики, до реализации Политики. Ссылочная реализация Политики получает свою информацию из конфигурационных файлов политики. См. Синтаксис Файла Реализации и Политики Политики По умолчанию для информации о ссылочной реализации Политики и синтаксис, который должен использоваться в файлах политики, которые это читает. Для получения информации об использовании Средства осуществления политики, чтобы создать файл политики (не будучи должен знать необходимый синтаксис), см. документацию Средства осуществления политики (для Соляриса) (для Windows).
"Домен защиты" охватывает CodeSource и полномочия, предоставленные кодировать от что CodeSource, как определено политикой безопасности в настоящий момент в действительности. Таким образом классы, подписанные теми же самыми ключами и от того же самого URL, помещаются в тот же самый домен, и класс принадлежит одному и только одному домену защиты. Классы, которые имеют те же самые полномочия, но являются из различных источников кода, принадлежат различным доменам.
Сегодня весь код, поставленный как часть SDK, считают системным кодом и выполняется в уникальном системном домене. У системного кода автоматически есть все полномочия.
Каждый апплет или приложение работают в его соответствующем домене, определенном его источником кода. Для апплета (или приложение, работающее под менеджером безопасности), чтобы быть позволенными выполнить защищенное действие (такое как чтение или запись файла), апплету или приложению нужно предоставить разрешение для того определенного действия.
Более определенно, всякий раз, когда доступ ресурса предпринимается, у всего кода, пересеченного потоком выполнения до той точки, должно быть разрешение для того доступа ресурса, если некоторый код потока не был отмечен как "привилегированный". Таким образом, предположите, что проверка управления доступом происходит в потоке выполнения, у которого есть цепочка многократных вызывающих сторон. (Думайте об этом как о многократных вызовах метода, которые потенциально пересекают границы домена защиты.), Когда AccessController
checkPermission
метод вызывается новой вызывающей стороной, основным алгоритмом для того, чтобы решить, позволить ли или отрицать, что запрошенный доступ следующие:
Если у кода для какой-либо вызывающей стороны в цепочке вызовов нет требуемого разрешения, AccessControlException бросается, если следующее не является истиной - вызывающая сторона, код которой предоставляют, упомянутое разрешение было отмечено как "привилегированный" (см. ниже), и все стороны, впоследствии вызванные этой вызывающей стороной (прямо или косвенно), у всех есть упомянутое разрешение.
Отмечание кода как "привилегированные" включения, часть доверяемого кода, чтобы временно включить доступу к большему количеству ресурсов чем доступна непосредственно коду, который вызывал это. Это необходимо в некоторых ситуациях. Например, приложение не может быть предоставлено прямой доступ к файлам, которые содержат шрифты, но системная утилита, чтобы вывести на экран документ должна получить те шрифты, от имени пользователя. Чтобы сделать это, системная утилита становится привилегированной, получая шрифты.
Если Вы не должны возвратить значение изнутри "привилегированного" блока, Вашего звонка doPrivileged
может быть похожим на следующее:
somemethod() { ...normal code here... AccessController.doPrivileged(new PrivilegedAction() { public Object run() { // privileged code goes here, for example: System.loadLibrary("awt"); return null; // nothing to return } }); ...normal code here... }
AccessController.doPrivileged
метод берет объект типа java.security.PrivilegedAction
и вызывает run
метод в привилегированном режиме. Реализация гарантирует, что полномочия будут отменяться после run
метод выполняется, даже если выполнение doPrivileged
прерывается асинхронным исключением.
PrivilegedAction
интерфейс с единственным методом, названным run
, это возвращает Объект. Вышеупомянутый пример показывает создание реализации того интерфейса, используя анонимный внутренний класс; конкретная реализация run
метод предоставляется. Когда звонок doPrivileged
делается, экземпляр реализации PrivilegedAction передают к этому. doPrivileged
вызовы метода run
метод от реализации PrivilegedAction после включения полномочиям, и возвратам run
возвращаемое значение метода как doPrivileged
возвращаемое значение (который игнорируется в этом примере).
Отметьте, что в зависимости от того, из чего "фактически состоял привилегированный код", Вам, возможно, придется произвести некоторые изменения из-за способа, которым работают внутренние классы. Например, если "привилегированный код" выдает исключение или попытки получить доступ к локальным переменным тогда, необходимо произвести некоторые изменения, как показано в последующих разделах этого документа.
Можно также вызвать doPrivileged
не используя анонимный внутренний класс, как в:
somemethod() { ...normal code here... MyAction mya = new MyAction(); // become privileged: AccessController.doPrivileged(mya); ...normal code here... } class MyAction implements PrivilegedAction { public MyAction() {}; public Object run() { // privileged code goes here, for example: System.loadLibrary("awt"); return null; // nothing to return } }
Будьте очень осторожны в своем использовании "привилегированной" конструкции, и всегда не забывайте делать привилегированный раздел кода как можно меньше, то есть, попытайтесь ограничить код в пределах run
метод к только коду, который должен быть выполнен с полномочиями, и сделать более общие вещи вне run
метод. Также отметьте что звонок doPrivileged
должен быть сделан в коде, который хочет включить его полномочиям. Не испытывайте желание записать служебный класс, который непосредственно вызывает doPrivileged
поскольку это могло привести к дырам в системе безопасности. Можно записать служебные классы для PrivilegedAction
классы, хотя, как показано в примере выше.
Если Вы должны возвратить значение, можно сделать что-то как следующее:
somemethod() { ...normal code here... String user = (String) AccessController.doPrivileged( new PrivilegedAction() { public Object run() { return System.getProperty("user.name"); } } ); ...normal code here... }
Отметьте, что это использование требует динамического броска на значении, возвращенном doPrivileged
. Альтернатива должна использовать a final
локальная переменная:
somemethod() { ...normal code here... final String user[] = {null}; AccessController.doPrivileged( new PrivilegedAction() { public Object run() { user[0] = System.getProperty("user.name"); return null; // still need this } } ); ...normal code here... }Еще одна альтернатива должна была бы записать неанонимный класс, который безопасно обрабатывает типы для Вас:
somemethod() { ...normal code here... GetPropertyAction gpa = new GetPropertyAction("user.name"); AccessController.doPrivileged(gpa); String user = gpa.getValue(); ...normal code here... } class GetPropertyAction implements PrivilegedAction { private String property; private String value; public GetPropertyAction(String prop) { property = prop;} public Object run() { value = System.getProperty(property); return value; } public String getValue() {return value;} }
Примечание там не является теперь никакими включенными преобразованиями типа, хотя run
метод все еще возвращает значение, таким образом, у Вас могла все еще быть "острота", если бы Вы хотели к:
somemethod() { ...normal code here... String user = (String) AccessController.doPrivileged( new GetPropertyAction("user.name")); ...normal code here... }
Если Вы используете анонимный внутренний класс, любые локальные переменные, к которым Вы получаете доступ, должны быть final
. Например:
somemethod() { ...normal code here... final String lib = "awt"; AccessController.doPrivileged(new PrivilegedAction() { public Object run() { // privileged code goes here, for example: System.loadLibrary(lib); return null; // nothing to return } }); ...normal code here... }
Переменная lib
должен быть объявлен final
если Вы намереваетесь использовать это в пределах привилегированного блока. См.
Если есть случаи, где невозможно сделать существующую переменную final
(потому что это устанавливается многократно), тогда можно создать новое final
переменная прямо перед вызовом doPrivileged
, и набор, что переменная, равная другой переменной. Например:
somemethod() { ...normal code here... String lib; ... // lib gets set multiple times so we can't make it final ... // create a final String that we can use inside of the run method final String fLib = lib; AccessController.doPrivileged(new PrivilegedAction() { public Object run() { // privileged code goes here, for example: System.loadLibrary(fLib); return null; // nothing to return } }); ...normal code here... }
Если действие, выполняемое в Вашем run
метод мог выдать "проверенное" исключение (тот, который должен быть перечислен в throws
пункт метода), тогда Вы должны использовать PrivilegedExceptionAction
интерфейс вместо PrivilegedAction
интерфейс:
somemethod() throws FileNotFoundException {
...normal code here...
try {
FileInputStream fis = (FileInputStream) AccessController.doPrivileged(
new PrivilegedExceptionAction() {
public Object run() throws FileNotFoundException {
return new FileInputStream("someFile");
}
}
);
} catch (PrivilegedActionException e) {
// e.getException() should be an instance of FileNotFoundException,
// as only "checked" exceptions will be "wrapped" in a
// PrivilegedActionException
.
throw (FileNotFoundException) e.getException();
}
...normal code here...
}
Если проверенное исключение выдается во время выполнения run
метод, это помещается в исключение "обертки" PrivilegedActionException, которое тогда выдается и должно быть поймано Вашим кодом, как иллюстрировано в вышеупомянутом примере..
doPrivileged()
метод может быть вызван, отражающим образом используя java.lang.reflect.Method.invoke()
. В этом случае полномочия, предоставленные в привилегированном режиме, не являются таковыми Method.invoke()
но неотражающего кода, который вызвал это. Иначе, системные полномочия могли ошибочно (или злонамеренно) быть присужденными пользовательскому коду. Отметьте, что подобные требования существуют при использовании существующего API через отражение.