【问题标题】:Applet java.io.FilePermission exception小程序 java.io.FilePermission 异常
【发布时间】:2013-09-11 19:53:37
【问题描述】:

我有一个用于 Intranet 站点的 Java 小程序,它需要访问客户端 PC 上的文件系统(特别是 LAN 共享)。这个小程序的功能类似于:

JSObject win;

public void init() {
    win=(JSObject) JSObject.getWindow(this);
    win.call("appletMsg", new Object[] {"<b>Applet Loaded</b>", "win"});
}

public void saveFile(String filepath, String filename) {
    File theDir = new File(filepath);
    try {
        if (theDir.exists()) { // This throws exception
            win.call("appletMsg", new Object[] {"Directory Exists", "win"});
        }
        else {
            win.call("appletMsg", new Object[] {"Creating Directory...", "msg"});
            if (theDir.mkdir()) {
                win.call("appletMsg", new Object[] {"Directory Created", "win"});
            }
            else win.call("appletMsg", new Object[] {"Directory Creation Failed!", "fail"});
        }
    }
    catch (Exception e) { // This exception is caught
        win.call("appletMsg", new Object[] {"Error Reading Directory!", "fail"});
        win.call("appletMsg", new Object[] {filepath, "fail"});
    }
    // More code for working with files, error happens above this
}

小程序背后的Javascript

// call applet method
function save() {
    document.myApplet.saveFile('\\\\LOCATION\\DIR\\DIR\\', 'test.txt');
}

// output responses from applet to div
function appletMsg(response, type) {
    document.getElementById('output').innerHTML+='<br><span class='+type+'>'+response+'</span>';
}

疑难解答/想法:

  • 小程序在我让 JS 调用 Java 方法之前工作 (参数在参数列表中,小程序完全重新加载时 需要,文件操作在 init() 方法中,恢复到这个工作但很糟糕的做法)
  • 小程序使用自证书签名
  • 我在 init() 方法中放置了一个 JFileChooser 以确保路径是 对,把它移到 saveFile() 方法,对话框没有 显示。它不会像使用 .exists() 在 Java 中调用,它确实会在 尝试/捕捉
  • 因为这在 init() 中有效,在 saveFile() 中无效,所以我只能假设 这是为了防止 JavaScript 本身访问文件系统??

【问题讨论】:

  • 如果您使用的是不受信任的(即自签名)证书,浏览器将不允许您访问文件系统。
  • 他们这样做,只是在 init() 方法中。有两种可能的解决方法,如 Yann39 指出的 doPrivilieged,或者在 init() 中定义一个执行回调的线程。

标签: java javascript security applet sandbox


【解决方案1】:

为了能够从 JavaScript 调用您的小程序函数,您必须使用访问控制器。 见documentation

那就试试吧:

public void saveFile(String filepath, String filename) {
    AccessController.doPrivileged(new PrivilegedAction() {
        public Object run() {
            File theDir = new File(filepath);
            try {
                if (theDir.exists()) { // This throws exception
                    win.call("appletMsg", new Object[] { "Directory Exists", "win" });
                } else {
                    win.call("appletMsg", new Object[] { "Creating Directory...", "msg" });
                    if (theDir.mkdir()) {
                        win.call("appletMsg", new Object[] { "Directory Created", "win" });
                    } else
                        win.call("appletMsg", new Object[] { "Directory Creation Failed!", "fail" });
                }
            } catch (Exception e) { // This exception is caught
                win.call("appletMsg", new Object[] { "Error Reading Directory!", "fail" });
                win.call("appletMsg", new Object[] { filepath, "fail" });
            }
            // More code for working with files, error happens above this
        }
    });
}

即使使用自签名证书也能正常工作,您只会收到安全警告。

永远记得使特权代码部分尽可能小。

【讨论】:

  • 谢谢,但它的工作方式有所不同。 init() 启动一个侦听布尔值的线程,在布尔值更改时它运行一个回调函数,并且由于该线程是在 init() 中定义的,因此它具有运行权限。幸运的是,这个应用程序位于 Intranet 站点上,因为它在破坏权限方面很重。除了文件操作之外,它还使用库通过 JNI 访问 TWAIN 驱动程序。我的整个功能基本上都是 doPrivileged。
  • 很高兴你成功了。看来使用一个线程监听一个布尔值和使用DoPrivileged的效果是一样的,可以参考this post
猜你喜欢
  • 2012-08-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-04
  • 2013-04-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多