12

我在位于http://localhost:8080/index.html的简单 HTML 页面上插入了一个 Java Applet :

<applet id="applet" code="SomeCode.class" archive="lib.jar" Width="1" Height="1"></applet>

Java Applet 有一个类似于以下代码的方法:

public void PostStuffToServer() {
  String server = "http://localhost:8080/PostHandler.ashx";
  URL u = new URL(server);
  URLConnection con = u.openConnection();
  con.setDoOutput(true);
  con.getOutputStream().write(stream.toByteArray());
  con.connect();
}

当我像这样从 JavaScript 执行小程序代码时:

obj = document.getElementById('applet');
obj.getClipboardImageURL();

我收到以下错误:

访问被拒绝(java.net.SocketPermission 127.0.0.1:8080 连接,解决)

似乎 Java 代码将域localhost解析为其等效的 IP 地址,因此引发了跨域安全限制。当我从http://127.0.0.1:8080/index.html执行相同的代码时,它工作正常。lib.jar 文件已签名。

有没有办法避免这种情况?

4

10 回答 10

14

我在安装Java 6 Update 22 后也遇到了同样的问题。我的小程序已经上线好几年了,没有报错。当我降级到版本 6 Update 21 时,一切正常。我的小程序没有签名。

解决方案:我花了一段时间才找到问题的原因。实际上,在我的情况下,有几个因素导致了安全错误。crossdomain.xml 文件解决了这个问题。Java 小程序尝试下载跨域文件,但失败了,甚至没有费心在 Java 控制台中显示错误(调试级别 5)。Java 尝试从我的域的 IP 地址 (http://ip-address/crossdomain.xml) 下载文件,而不是我网站的根 (http://domain-name/crossdomain.xml)。我想这对安全方面更好?然后我必须配置网络服务器以在 IP 地址上公开跨域文件。就我而言,出于安全原因,我已经删除了 ISS 中的默认网站,并且不得不创建一个新网站。然后我发现 java 小程序不适用于我在 flash 中使用的跨域文件:

<?xml version="1.0"?>
<cross-domain-policy>
   <site-control permitted-cross-domain-policies="master-only"/>
   <allow-http-request-headers-from domain="*" headers="*"/>
   <allow-access-from domain="*" />
</cross-domain-policy>

我必须从 xml 文件中删除 site-control 和 allow-http-request-headers-from 节点才能使小程序工作。

于 2010-11-10T07:25:16.307 回答
10

我想我来得太晚了,但无论如何......伙计们,你无法相信这个问题的解决方案是多么容易。

问题是从 JavaScript 调用的 Java 小程序代码仅具有 JavaScript 代码和您的小程序代码交集的权限 - 不知何故,JavaScript 的权限被视为较少,这会导致此异常。

这是我所做的:假设你有一个innocentFunc()抛出 java.net.SocketPermission 异常的函数,所以你的代码是这样的:

String s = innocentFunc();

现在你可以做的就是把它改成这样:

String s = AccessController.doPrivileged(
      new PrivilegedAction<String>() {
          public String run() {
              return innocentFunc();
          }
        }
     );

这个 AccessController 调用基本上向 Java 虚拟机表明它运行的代码不应该服从来自调用链的权限,而应该只服从调用者自己的权限。

当然,只有在确保此innocentFunc调用不会做任何坏事(即使被恶意代码调用)之后,您才应该执行此类操作。

于 2011-06-06T08:13:36.137 回答
2

我在更新 22 中得到了同样的结果,而不是更新 21。

我正在使用通过 JavaScript 控制的TinyPlayer小程序。

我正在从与加载小程序的页面相同的域(mydomain.example.com,IP 1.2.3.4)加载音频文件 - 使用相对 URL 引用所有内容。

当我尝试播放音频时,它无法播放并且我得到:拒绝访问(java.net.SocketPermission 1.2.3.4:80 connect,resolve)

查看访问日志,我在这发生之前收到了对 crossdomain.xml 的请求。但问题是 Java 不是从 mydomain.example.com/crossdomain.xml 请求 crossdomain.xml ......而是从 1.2.3.4/crossdomain.xml

似乎对我有用的解决方法是设置一个响应 IP 地址 1.2.3.4 的虚拟主机,并给它一个 crossdomain.xml,以便 Java 可以在它所在的(错误)位置找到 crossdomain.xml寻找它。

我刚刚测试了以下内容:

<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM "http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
  <allow-access-from domain="*" />
</cross-domain-policy>

...但可能会使其更具限制性。

在那里,音频可以正确播放。

于 2010-11-13T02:21:46.790 回答
2

只是补充一点,这里有一些东西与我遇到的问题完全匹配——它特别提到了用 JavaScript 控制一个小程序。

http://www.oracle.com/technetwork/java/javase/6u22releasenotes-176121.html

CVE-2010-3560 的修复可能会导致在新 Java 插件中运行的某些 Java 小程序停止工作,如果它们嵌入包含调用 Java 以执行需要网络安全权限的操作的 JavaScript 的网页中。在某些情况下,如果解析原始网页 URL 主机名的名称服务未返回匹配的名称作为反向地址查找的结果,这些小程序可能会因网络安全异常而失败。

他们的建议是在 DNS 中添加一个特别疯狂的 just-for-Java A 记录,例如:

10.11.12.13    foo.bar.com.auth.13.12.11.10.in-addr.arpa
于 2010-11-13T12:16:54.873 回答
1

IIRC,JavaScript 同源策略阻止访问相同主机/不同端口。插件的 LiveConnect 仅对 localhost 强制执行此策略。

于 2010-11-09T15:14:35.933 回答
1

请参阅:http: //download.oracle.com/javase/tutorial/deployment/applet/security.html

未签名的小程序可以执行以下操作:

他们可以与他们来自的主机建立网络连接。

如果 Java 不将原始系统解析为 localhost,则小程序将无法打开套接字。

于 2011-02-27T20:21:30.813 回答
1

我遇到了类似的问题,只有当我使用“localhost”作为带有小程序的页面的 URL 的一部分时才会发生这种情况。当我使用带有实际主机名或 IP 地址的 URL 作为 URL 的一部分时,问题没有发生。我不确定这是 Java 插件的缺陷...

例如,当我使用http://localhost:9080/app_id/appletPage之类的 URL 时,就会出现问题,但是当我通过使用实际 IP 或主机名来使用 URL 时,问题并没有发生。

于 2011-07-28T09:11:31.810 回答
0

我认为不可能使 crossdomain.xml 文件更具限制性,目前 Java 小程序仅支持 (domain="*")

见这里http://www.oracle.com/technetwork/java/javase/index-135519.html#CROSSDOMAINXML

于 2010-11-25T23:38:34.740 回答
0

您应该检查您的虚拟目录权限。

于 2010-11-29T06:17:26.663 回答
0

上面@Kristian 的更新挽救了我的一天。

access denied (java.net.SocketPermission <server_ip>:<server port> connect,resolve)从 Web 应用程序中的小程序获得。

我们的 DNS 发生了变化,因此应用服务器的负载均衡器的 IP 没有解析为带域的名称。因此,从小程序返回服务器的可疑“跨域连接”被阻止。我添加了 crossdomain.xml

<?xml version="1.0"?> <cross-domain-policy> <allow-access-from domain="*" /> </cross-domain-policy>

<tomcat-home>/webapps检查它是否可以访问http://<server name>:<server port>/crossdomain.xml

于 2014-03-26T12:20:14.337 回答