4

我有一个简单的自签名小程序(使用 keytool 和 jarsigner 完成):

public class NetAppletLauncher extends JApplet {

    private static final long serialVersionUID = 1L;

    public void init() {
        exec("notepad c:/hello.txt");
    }

    public void exec(String command) {

        try {

            // launch EXE and grab stdin/stdout and stderr
            Process process = Runtime.getRuntime().exec(command);
            //      OutputStream stdin = process.getOutputStream();
            InputStream stderr = process.getErrorStream();
            InputStream stdout = process.getInputStream();

            // "write" the parms into stdin
//          stdin.write(arguments.getBytes());
//          stdin.flush();
//          stdin.close();

            // clean up if any output in stdout
            String line = "";
            BufferedReader brCleanUp = new BufferedReader(new InputStreamReader(stdout));
            while ((line = brCleanUp.readLine()) != null) {
                //System.out.println ("[Stdout] " + line);
            }
            brCleanUp.close();

            // clean up if any output in stderr
            brCleanUp = new BufferedReader(new InputStreamReader(stderr));
            while ((line = brCleanUp.readLine()) != null) {
                //System.out.println ("[Stderr] " + line);
            }
            brCleanUp.close();

        } catch (Exception exception) {
            exception.printStackTrace();
        }

    }

}

基本上,它的作用是执行“记事本 c:/hello.txt”。

然后我将小程序嵌入到 html 中:

<applet id='applet' name='applet' archive='NetAppletLauncher1.jar' code='src.NetAppletLauncher' width='100' height='100' MAYSCRIPT ></applet>

当我访问该页面时,JRE 启动并询问我是否要启动此小程序以及是否信任它。我按确定。然后记事本开始 - 它应该。这里没问题。

但随后我将其添加到 HTML 页面中:

<p class="link" onclick="document.applet.exec('calc');">remote desktop2</p>

现在,当我按下此文本时,应该开始计算 - 对吧?但这给了我:

java.security.AccessControlException: access denied (java.io.FilePermission <<ALL FILES>> execute)
    at java.security.AccessControlContext.checkPermission(Unknown Source)
  • 这是怎么回事?为什么它现在给我一个安全异常,但它之前可以启动记事本?
4

4 回答 4

6

Java 2 安全模型要求(大致)堆栈上的每一帧都必须被授予访问控制上下文 (acc) 的权限才能拥有该权限。JavaScript 在堆栈上,没有文件访问权限。

于 2009-07-01T11:39:02.500 回答
5

用Java解决了这个问题:

exec(getParameter("command"));

然后在 JavaScript 中:

<script type="text/javascript">

function exec( command ) {

    var applet = "<applet id='applet' style='visibility: hidden' name='applet' archive='NetAppletLauncher4.jar' code='src.NetsetAppletLauncher' width='20' height='20' MAYSCRIPT ><param name='command' value='" + command + "' />Sorry, you need a Java-enabled browser.</applet>";

    var body = document.getElementsByTagName("body")[0];
    var div = document.createElement("div");
    div.innerHTML = applet;
    body.appendChild(div);

}

</script>
于 2009-07-01T12:01:14.950 回答
1

我同意:禁止从 javascript 操作已签名的小程序,解决方法是在页面文档中重写 javascript 中的小程序标签。

我发现这个来源有一点理论证明我们是对的 http://docs.oracle.com/javase/tutorial/deployment/applet/security.html#jsNote

于 2011-12-15T15:15:49.677 回答
1

实际上,从 javascript 调用小程序的行为就像调用未签名的小程序(如 jsnote 中所述:http ://docs.oracle.com/javase/tutorial/deployment/applet/security.html#jsNote 。 '正在使用一个不允许更改的类,但由于您是 java 类的作者,因此您始终可以包装您需要从 javascript 调用的特定方法,以便在特权模式下执行,如下所示:

AccessController.doPrivileged(new PrivilegedAction<String>() {
    @Override
    public String run() {
        exec(command);
        return null;
    }
});

它应该可以正常工作。(这是@Jean-Philippe Jodoin 在赞成评论中所建议的,但那里提供的链接已损坏)

于 2012-12-28T23:23:08.470 回答