我有一个简单的自签名小程序(使用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();
}
}
}
基本上,它的作用是执行'notepad c:/hello.txt'。
然后我将applet嵌入html:
<applet id='applet' name='applet' archive='NetAppletLauncher1.jar' code='src.NetAppletLauncher' width='100' height='100' MAYSCRIPT ></applet>
当我访问该页面时,JRE启动并询问我是否要启动此applet并且如果我信任它。我按好了。然后记事本开始 - 应该如此。这里没问题。
但是我将其添加到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)
答案 0 :(得分:6)
Java 2安全模型(大致)要求必须为访问控制上下文(acc)授予堆栈中的每个帧以获得该权限。 JavaScript位于堆栈中,没有文件访问权限。
答案 1 :(得分: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>
答案 2 :(得分:1)
我同意:禁止从javascript操作已签名的applet,解决方法是在页面文档中的javascript中重写applet标记。
我发现这个来源有一些理论证明我们是对的 http://docs.oracle.com/javase/tutorial/deployment/applet/security.html#jsNote
答案 3 :(得分:1)
实际上,从javascript调用applet就像调用unsigned applet一样(在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提出的评论中的建议,但提供的链接已经破了)