我不确定我是否正确理解了您的最后评论。正如您所说的两个(对我而言)不同的事情:
- 您使用 plugin.jar (这对我来说意味着您的 java 调用 javascript 函数)
- “我从 Javascript 调用相同的函数”(这对我来说意味着你的 javascript 调用 java 函数)
我认为后一个是正确的解释。
如果您只是调用不做任何与安全相关的事情的 java 方法(通过 liveconnect),一切都可以。你可以直接在你的javascript代码中做(假设applet with id="myapplet"
) 。myapplet.safeMethod();
从 javascript 调用 java 方法的主要问题是,这些方法通常对 applet 进行限制,这些调用似乎在 JVM 中运行在与 applet 本身不同的上下文中。因此被视为非特权代码,您将获得AccessControlException
. 虽然例如在我的其他答案中,由小程序本身执行的方法获得正确的权限并被执行。
现在,如果您在第2.8 节 JavaScript 到 Java 调用的安全模型中阅读新 Java™ 插件技术中的 LiveConnect 支持, SUN 状态
当进行 JavaScript 到 Java 调用时,JavaScript 代码被建模为好像它来自一个不受信任的小程序,其代码源是文档库(即包含文档的目录的 URL)。
我将其解读为:如果 applet 和 javascript 来自同一个站点,那么 javascript-to-java 调用应该以与 applet 本身相同的权限运行。在我们的例子中,这意味着我们在grant
.
但这仅适用于我的 Opera。FF 和 IE6 都抛出AccessControlException
. 但它可能仍然适用于所有浏览器。
下面的代码有两个方法userName2()
和userName()
. userName2()
所有浏览器中的 WFM。userName()
仅适用于 Opera。通过按下 html 页面上的按钮进行检查。
如您所见userName2()
,对于真正的用例(只能调用一次),它不能像这样使用。但是您可以在遇到类似问题时查看其他人提出的解决方案,并相应地扩展userName2()
使用 LiveConnect 的 Java 小程序
此外,您可能会考虑一些我没有尝试过的东西。所有来自 javascript-to-java 的调用都不会做任何与安全相关的事情,只是(如果需要)传入数据并立即返回。然后小程序执行实际工作(如上面显示的链接中所示)。JSObject
然后,当完成后,小程序可以通过( plugin.jar )向 html 页面触发回调
测试应用程序.java
import java.applet.Applet;
import java.awt.*;
import java.security.AccessControlException;
public class TestApp extends Applet {
Label output = new Label("What is the value of user.name?");
String userName;
Thread access = new Thread() {
@Override
public void run() {
try {
userName = System.getProperty("user.name");
} catch (AccessControlException e) {
userName = "Oops, failed in thread. No read permissions!";
}
}
};
public void init() {
setLayout(new BorderLayout());
add(BorderLayout.CENTER, output);
}
public String userName2() throws InterruptedException {
access.start();
access.join();
output.setText(userName);
return userName;
}
public String userName() {
String userName = "Oops, failed in liveconnect-context. No read permissions!";
try {
userName = System.getProperty("user.name");
} catch (AccessControlException e) {
e.printStackTrace();
}
output.setText(userName);
return userName;
}
}
测试.html
<html><head><title>test</title></head><body>
<applet id="myapplet" code="TestApp" width="350px" height="80px"></applet><br>
<input type="button" value="liveconnect version" onclick="javascript:alert(myapplet.userName());"><br>
<input type="button" value="hacky thread version" onclick="javascript:alert(myapplet.userName2());">
</body></html>
策略:.java.policy(在 C:/Documents and Settings/[USERNAME]/ 中手动创建,注意前导.
)
grant codeBase "http://[domain].xxx/-" {
permission java.util.PropertyPermission "user.name", "read";
};