2

经过大量阅读和测试后,我无法通过 codeBase 授予选项授予 Intranet 小程序的所有权限。此小程序需要完全权限,因为它必须访问 OCR 读取器(也将图像文件写入 HDD)和其他此类外部设备的驱动程序库。

我已经配置了我的 java.policy 文件并添加了以下内容:

grant codebase "http://myIntranetServer/-" { permission java.security.AllPermission; };

在控制台中重新加载策略文件,甚至重新启动浏览器后,我的许多操作都收到 java.security.AccessControlException:access denied,包括读取默认情况下未授予的“user.name”系统属性。

对于调试,我还尝试了默认授予所有权限并且它可以工作,所以我的问题基本上与 de codeBase 选项有关。我正在使用 JRE1.6-u17 运行 Windows 7 和 linux 客户端,并且两者具有相同的行为。

任何人都可以帮忙吗?

提前致谢,

马德拉A

4

2 回答 2

4

我不确定我是否正确理解了您的最后评论。正如您所说的两个(对我而言)不同的事情:

  • 您使用 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";
};
于 2009-11-24T01:05:35.377 回答
0

现在自己试了一下。

  • 位于服务器上的类文件 + html 文件http://[domain].xxx/~someusername/somefolder/
  • 位于本地文件系统上的类文件 + html 文件C:/Documents and Settings/[USERNAME]/Desktop/somefolder

策略:(.java.policy位于 C:/Documents and Settings/[USERNAME]/。注意前导.

使用这些小程序时工作和显示[USERNAME]

grant codeBase "file:///-" {
  permission java.util.PropertyPermission "user.name", "read";
};
grant codeBase "http://[domain].xxx/-" {
  permission java.util.PropertyPermission "user.name", "read";
};

然后使用这些(在java控制台中重新加载策略文件)小程序无法显示[USERNAME]

grant codeBase "file:///c/*" {
  permission java.util.PropertyPermission "user.name", "read";
};
grant codeBase "http://[domain].xxx/*" {
  permission java.util.PropertyPermission "user.name", "read";
};

上诉:TestApp.java

import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;
import java.security.*;

public class TestApp extends Applet {
  Label output = new Label("What is the value of user.name?");
  public void init() {
    Button button = new Button("Click me!");
    setLayout(new BorderLayout());
    add(BorderLayout.NORTH, button);
    add(BorderLayout.CENTER, output);
    button.addActionListener(
      new ActionListener() {
        @Override
        public void actionPerformed( ActionEvent ev ) {
          try {
            output.setText(System.getProperty("user.name"));
          } catch (AccessControlException e) {
            output.setText("Oops, failed. No read permissions");
          }
        }
      }
    );
  }
}

HTML:index.html

<html><body>
  <applet code="TestApp.class" width=350 height=80></applet>
</body></html>

我现在有点困惑。您声明上述grant声明不起作用,同时声明“默认授予所有权限......有效”?

几个问题

  • 你使用的是什么浏览器?
  • 你编辑了哪个 java.policy 文件/你把它放在哪里
  • URL 到底是什么样子的?myIntranetServer 是否可以通过 DNS 解析?如果不是,java可能在应用规则时遇到问题
于 2009-11-18T00:35:36.953 回答