Не AccessController.doPrivileged дает потокам JavaScript разрешения подписанного апплета?
Я смотрю на подписанный апплет, который сильно вызывается из JavaScript. Очевидно, что потоки, исходящие из JavaScript, более сильно изолированы, чем любой поток, запущенный непосредственно из Java. Например, если поток JavaScript вызывает в апплет и регистрирует что-то, что вызывает откат файла журнала, создается исключение безопасности. Любой поток, запущенный непосредственно в апплете, не будет испытывать это исключение безопасности. Решение здесь с log4j-это использовать асинхронный аппендер.
но с другими исключениями безопасности (например, использование оси Apache в подписанном апплете, но в потоке JavaScript) нет очевидного способа иметь некоторый асинхронный поток. Предположим, у меня есть следующий код, который при вызове из потока Java будет работать, а при вызове через JavaScript произойдет сбой с SecurityException:
public void someMethodCalledFromJavaScript() {
// Stuff that would throw a SecurityException
}
Я вижу три варианта, но они не могут все быть в силе. Ради этого обсуждения игнорируйте независимо от того, будет ли выполнение синхронным или асинхронным, поскольку это легко управляется. Мне трудно понять детали модели безопасности. Вот мои три возможных варианта:--8-->
-
запустите новый поток (будет ли это работать?):
public void someMethodCalledFromJavaScript() { new Thread(new Runnable() { public void run() { // Stuff that would throw a SecurityException } }).start(); }
-
у апплета есть поток, готовый к работе в любое время, запускаемый через поток JavaScript-origin (сильно упрощенный код здесь):
private volatile boolean doit = false; // This code is running in a Thread, started @ Applet init time public void alwaysWaiting() { while (true) { if (doit) { doit = false; // Stuff that would throw a SecurityException } } } public void someMethodCalledFromJavaScript() { doit = true; }
-
Используйте AccessController.doPrivileged:
public void someMethodCalledFromJavaScript() { AccessController.doPrivileged(new PrivilegedAction() { public Object run() { // Stuff that would throw a SecurityException return null; } }); }
по тому, что я читал о AccessController.doPrivileged
, вы запускаете с пересечением текущих privs безопасности и privs домена безопасности кода, который вы вызываете. Это не имеет смысла для меня, как будто вы бежите с пересечение низкого и высокого уровня безопасности домена, вы будете просто иметь низкий уровень безопасности домена. Очевидно, я не понимание чего-то.
конкретные SecurityException
Я вижу это:
java.security.AccessControlException: access denied (java.lang.RuntimePermission accessDeclaredMembers)
но, конечно, мне любопытно об общем случае в контексте JavaScript, вызывающего подписанный апплет, и как я могу позволить потоку, созданному JavaScript, работать с priv подписанного апплета, как если бы это был поток, который возник исключительно внутри апплета.
какие варианты выше будут даже работать, и которые лучше, чем другие, и почему.
2 ответов
- "запустите новый поток (будет ли это работать?)"
не будет работать по причинам, упомянутым ниже
- у апплета есть поток, готовый к работе в любое время, запускаемый через поток JavaScript-origin
будет работать, конечно, но это более болезненно, чем вызов doPrivileged
, но имеет тот же эффект семантически.
- Используйте AccessController.doPrivileged
Да это будет работать.
каждая проверка контроля доступа проверяет набор всех кадров стека в стеке текущего потока (включая кадр стека, ведущий к созданию экземпляра текущего потока, рекурсивно). Если есть doPrivileged
кадр, кадры, ведущие к этому кадру, не включены в набор (но фактический doPrivileged
рама is включил).
если проверяемая привилегия находится не в каждом кадре в этом наборе, проверка неудачи.
другими словами, текущие привилегии потока являются пересечением привилегий в этом наборе.
так, например, если привилегированный код doPrivileged
s какой-то непривилегированный код, который пытается открыть файл, проверка завершится неудачей. Аналогично, если непривилегированный код doPrivileged
s привилегированный код, который открывает файл, проверка завершится ошибкой. Но если непривилегированный код вызывает привилегированный код, а привилегированный код, в свою очередь, вызывает doPrivileged
чтобы открыть файл, проверка будет преуспевать.
теоретически, ты должны быть в состоянии только предоставить вашей кодовой базе Java необходимые привилегии (возможно, доступ к некоторому изолированному каталогу), а затем предоставить то же самое привилегии кода JavaScript, который будет использовать этот привилегированный код, но я сомневаюсь, что любой браузер имеет такие функции. Я удивлен, что JavaScript даже работает в другом домене защиты, чем Java.
я никогда не делал JavaScriptJava interop, но кажется, независимо от того, что вам придется сделать методы, которые вызываются JavaScript use doPrivileged
блоки на весь организм.
EDIT: как сами сказал, Быть осторожно при вызове doPrivileged
блоки в привилегированном коде (и прочитайте его ответ).
Я бы пошел с doPrivileged. Просто имейте в виду, что все, у кого есть доступ к вашему апплету, могут загрузить его и поместить на свой сайт и иметь свой собственный вредоносный javascript, который вы не представляли.
последствия для безопасности других решений в значительной степени одинаковы (EDIT: хотя создание нового потока не работает, как указал Longpoke), но они сложнее. Так что я не вижу в них никакой пользы.
в AccessController.doPrivileged рассматривает домен защиты только непосредственного вызывающего абонента. В вашем примере класса, где ваш someMethodCalledFromJavaScript метод определен. Если это доверенный класс в подписанном jar, не имеет значения, что его вызывает ненадежный Javascript.