Запуск Javascript в Java: отказ в FilePermission

Запустив Javascript в Java, я получаю доступ к FilePermission как при чтении, так и при записи. Это происходит, когда Javascript обращается к методу Java, который выполняет некоторые файловые операции. Моя программа Java Swing GUI сама не имеет проблем с чтением и записью файлов на локальный диск.

Используя следующий подход для оценки сценария:

URL url = new URL(scriptURL);
InputStream is = url.openStream();
Reader reader = new InputStreamReader(is, Constants.DEFAULT_CHARSET);
engine.eval(reader);

Я могу обойти это, добавив следующее в Java по умолчанию java.policy

grant {
    permission java.io.FilePermission "<<ALL FILES>>", "read, write";
};

Это не справедливое решение. Всем пользователям моей программы потребуется добавить ее в свою собственную политику Java.

Если бы я предоставил свой собственный файл политики Java, это можно было бы использовать при запуске JAR. Однако, поскольку программа выполняется через Java Web Start, это не вариант. Запуск Java Web Start в командной строке может предоставить дополнительный файл политики Java, но это не удобная опция. Добавление свойства ресурса JNLP с дополнительным файлом политики Java не работает, так как мой JNLP не подписан (хотя мой JAR подписан).

SEVERE: http://machine/path/to/someJavaScript.js: access denied ("java.io.FilePermission" "/home/username/.program/cache/image8761533877202123654.img" "read")
java.security.AccessControlException: access denied ("java.io.FilePermission" "/home/username/.program/cache/image8761533877202123654.img" "read")
at java.security.AccessControlContext.checkPermission(AccessControlContext.java:457)
at java.security.AccessController.checkPermission(AccessController.java:884)
at java.lang.SecurityManager.checkPermission(SecurityManager.java:549)
at com.sun.javaws.security.JavaWebStartSecurity.checkPermission(Unknown Source)
at java.lang.SecurityManager.checkRead(SecurityManager.java:888)
at sun.awt.SunToolkit.checkPermissions(SunToolkit.java:912)
at sun.awt.SunToolkit.getImageFromHash(SunToolkit.java:737)
at sun.awt.SunToolkit.getImage(SunToolkit.java:752)
at javax.swing.ImageIcon.<init>(ImageIcon.java:159)
at javax.swing.ImageIcon.<init>(ImageIcon.java:186)
at com.company.gui.ImageHelperStore.get(ImageHelperStore.java:366)
at com.company.gui.BaseComponent.getIcon(BaseComponent.java:1046)
at com.company.gui.GUIScripter$Helper.getIcon(GUIScripter.java:152)
at jdk.nashorn.internal.scripts.Script$\^eval\_.:program(<eval>:32)
at jdk.nashorn.internal.runtime.ScriptFunctionData.invoke(ScriptFunctionData.java:636)
at jdk.nashorn.internal.runtime.ScriptFunction.invoke(ScriptFunction.java:229)
at jdk.nashorn.internal.runtime.ScriptRuntime.apply(ScriptRuntime.java:387)
at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:437)
at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:401)
at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:397)
at jdk.nashorn.api.scripting.NashornScriptEngine.eval(NashornScriptEngine.java:147)
at javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:249)
at com.company.gui.GUIScripter.initializeScript(GUIScripter.java:392)
at com.company.gui.GUIScripter.postInitialize(GUIScripter.java:346)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:301)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:756)
at java.awt.EventQueue.access$500(EventQueue.java:97)
at java.awt.EventQueue$3.run(EventQueue.java:709)
at java.awt.EventQueue$3.run(EventQueue.java:703)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:726)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)e here

1 ответ

Решение

Если вы загружаете сценарий из String или из произвольного экземпляра java.io.Reader, тогда механизм сценариев nashorn обрабатывает сценарий как "ненадежный" и, таким образом, дает ему только разрешения "песочницы" (независимо от того, какие разрешения даны без "codeBase" в вашей безопасности). политика). Но если вы хотите, чтобы ваши jar-файлы имели те же права доступа (т.е. наследовать разрешения jar-файла в ваших скриптах), вам нужно загрузить скрипт, используя jdk.nashorn.api.scripting.URLReader ( https://docs.oracle.com/javase/8/docs/jdk/api/nashorn/jdk/nashorn/api/scripting/URLReader.html)

Образец кода

Вы можете скопировать следующие файлы в свой домашний каталог. Чтобы скомпилировать и запустить это, вы можете использовать скрипт run.sh ниже. В этом примере для загрузки сценария используется URLReader. И поэтому скрипт "наследует" разрешения, предоставленные файлу jar.

Файл: Main.java

import javax.script.*;
import java.net.URL;
import jdk.nashorn.api.scripting.URLReader;

public class Main {
    public static void main(String[] args) throws Exception {
        ScriptEngineManager m = new ScriptEngineManager();
        ScriptEngine e = m.getEngineByName("nashorn");
        e.eval(new URLReader(Main.class.getResource("test.js")));
    }
}

Файл test.js

print("about to exit...");
java.lang.System.exit(0);

Файл test.policy

grant codeBase "file:${user.dir}/test.jar" {
    permission java.security.AllPermission;
};

Файл run.sh

javac Main.java
jar cvf test.jar Main.class test.js
java -Djava.security.manager -Djava.security.policy=test.policy -cp test.jar Main
Другие вопросы по тегам