【发布时间】:2013-01-28 17:54:24
【问题描述】:
我有一个网络应用程序,它需要能够在客户端计算机上本地打开文件,并能够在编辑后保存文件。 Web 应用程序在服务器上的一个文件夹中生成一个文档,该文件夹通过 WebDAV 和 FTP 共享出去,该文件夹安装在客户端计算机上。
我不能使用 file:// 类型的 URI,因为它不允许保存回服务器。
我打算尝试使用嵌入在处理此文件打开的 Web 应用程序中的小型 Java 小程序来解决问题,但我在 Java 中的权限方面遇到了困难。 (Java 不是我的专业领域)。无论如何,我已将代码范围缩小到以下内容:
localfile.html
<html>
<body>
<input id="input" value="Call from Javascript" type="button" onclick="callApplet('/Users/conor/1.txt')">
<script type='text/javascript'>
function callApplet(path) {
applet = document.getElementById('localfile');
applet.openFile(path);
}
</script>
<applet id="localfile" code="localfile.class" archive="localfile.jar" width="150" height="50"></applet>
</body>
</html>
localfile.java
import java.applet.*;
import java.awt.*;
import java.util.*;
import java.lang.*;
import java.text.*;
import java.awt.event.*;
import java.io.*;
import java.security.*;
public class localfile extends Applet {
public localfile() {
Panel p = new Panel();
p.add(new Button("Call from Java"));
add("North",p);
}
public void openFile(String path) {
System.out.println("File: " + path);
final File ffile = new File(path);
System.out.println("Got file.");
if (Desktop.isDesktopSupported()) {
System.out.println("Desktop is supported.");
final Desktop desktop = Desktop.getDesktop();
System.out.println("Got Desktop Handle.");
try {
desktop.open(ffile);
} catch(Exception ex) {
ex.printStackTrace();
}
System.out.println("File Opened.");
}
}
public boolean action(Event evt, Object arg) {
openFile("/Users/conor/1.txt");
return true;
}
}
我已经编译、创建了一个 jar 文件并从 java 源对其进行了签名。
这会生成一个带有两个按钮的页面——一个 Java 按钮(用于测试)和一个 Javascript 按钮。 Java 按钮按预期工作正常 - 我可以保存文件等。我想将文件路径传递给小程序,所以它确实是我希望开始工作的 Javascript 按钮。 Javascript 会抛出以下内容:
堆栈跟踪
java.security.AccessControlException: access denied ("java.awt.AWTPermission" "showWindowWithoutWarningBanner")
at java.security.AccessControlContext.checkPermission(AccessControlContext.java:366)
at java.security.AccessController.checkPermission(AccessController.java:560)
at java.lang.SecurityManager.checkPermission(SecurityManager.java:549)
at java.awt.Desktop.checkAWTPermission(Desktop.java:239)
at java.awt.Desktop.open(Desktop.java:267)
at localfile.openFile(localfile.java:27)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at sun.plugin.javascript.JSInvoke.invoke(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at sun.plugin.javascript.JSClassLoader.invoke(Unknown Source)
at sun.plugin2.liveconnect.JavaClass$MethodInfo.invoke(Unknown Source)
at sun.plugin2.liveconnect.JavaClass$MemberBundle.invoke(Unknown Source)
at sun.plugin2.liveconnect.JavaClass.invoke0(Unknown Source)
at sun.plugin2.liveconnect.JavaClass.invoke(Unknown Source)
at sun.plugin2.main.client.LiveConnectSupport$PerAppletInfo$DefaultInvocationDelegate.invoke(Unknown Source)
at sun.plugin2.main.client.LiveConnectSupport$PerAppletInfo$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at sun.plugin2.main.client.LiveConnectSupport$PerAppletInfo.doObjectOp(Unknown Source)
at sun.plugin2.main.client.LiveConnectSupport$PerAppletInfo$LiveConnectWorker.run(Unknown Source)
at java.lang.Thread.run(Thread.java:722)
我也尝试过将 desktop.open 调用嵌入到 doPrivileged 块中,如下所示:
AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
try {
desktop.open(ffile);
} catch(Exception ex) {
ex.printStackTrace();
}
return null;
}
});
但这会为 javascript 和 java 按钮引发错误,如下所示:
java.lang.SecurityException: class "localfile$1" does not match trust level of other classes in the same package
任何帮助将不胜感激。
【问题讨论】:
-
考虑为此使用JWS file service。它甚至可以被沙盒小程序使用。
-
感谢您的反馈!我确实需要调用 desktop.open() 方法才能打开相关的应用程序来处理文件类型。我对文件内容并不感兴趣(无论如何在帮助程序小程序中)。小程序不对文件内容进行任何处理,而仅用作在客户端桌面上为给定文件类型打开相关应用程序的工具。顺便说一句,系统用于基于 Web 的文档管理。
-
“需要调用 desktop.open()” 我的错。我的浏览器中同时打开了几个“小程序权限问题”问题,我很困惑。
-
“我也试过.. doPrivileged 块” 是的,这个需要。 1)编辑主代码以显示您如何使用它。 2)重建罐子。 3) 检查代码库中没有“松散”的类文件。 4) 在浏览器中刷新类缓存并重新加载小程序。
-
安全模型似乎不允许这样做,除非通过其他 Javascript 将小程序添加到文档中:stackoverflow.com/questions/1068271/…
标签: java javascript security applet