【问题标题】:access denied (java.net.SocketPermission 127.0.0.1:8080 connect,resolve)访问被拒绝(java.net.SocketPermission 127.0.0.1:8080 连接,解决)
【发布时间】:2010-11-09 15:06:06
【问题描述】:

我在位于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 connect,resolve)

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

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

【问题讨论】:

  • 尝试签署 lib.jar 和您正在使用的所有其他外部 jar 文件
  • 不要使用 localhost!我还将解释原因:根本无法保证 localhost 是 127.0.0.1。也总是使用小程序中的getCodeBase(),不要使用硬编码的位置。

标签: java javascript security applet liveconnect


【解决方案1】:

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

解决方案: 我花了一段时间才找到问题的原因。实际上,在我的情况下,有几个因素导致了安全错误。 crossdomain.xml 文件解决了这个问题。 Java 小程序尝试下载跨域文件,但失败了,甚至没有费心在 Java 控制台中显示错误(调试级别 5)。 Java 尝试从我的域 (http://ip-address/crossdomain.xml) 的 IP 地址下载文件,而不是我网站的根 (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 节点才能使小程序工作。

【讨论】:

    【解决方案2】:

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

    问题是从 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 调用不会做坏事(即使被恶意代码调用)之后,您才应该这样做。

    【讨论】:

    • 我只是想回复一个类似的解决方案。看到你的,我冒昧地编辑它,添加一些解释。
    【解决方案3】:

    补充一点,这里有一些内容与我遇到的问题完全一致 - 它特别提到了使用 JavaScript 控制小程序。

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

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

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

    10.11.12.13    foo.bar.com.auth.13.12.11.10.in-addr.arpa
    

    【讨论】:

      【解决方案4】:

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

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

      我正在从与加载小程序的页面相同的域(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 ...而是从 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>
      

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

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

      【讨论】:

        【解决方案5】:

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

        【讨论】:

        • 我不知道 thies 是什么意思?这是否意味着如果我将此代码部署到生产环境(例如 www.productiondomain.com),该代码将正常工作并且不会解析为 IP 地址?
        • 应该可以。 (当然,除非该主机名解析为 localhost。)
        • 您可以从小程序连接到同一主机上的任何端口
        【解决方案6】:

        见:http://download.oracle.com/javase/tutorial/deployment/applet/security.html

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

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

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

        【讨论】:

          【解决方案7】:

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

          例如,当我使用http://localhost:9080/app_id/appletPage 之类的 URL 时出现问题,但当我使用实际 IP 或主机名使用 URL 时,问题并未发生。

          【讨论】:

            【解决方案8】:

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

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

            【讨论】:

              【解决方案9】:

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

              【讨论】:

                【解决方案10】:

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

                我从 Web 应用程序的小程序中获得了 access denied (java.net.SocketPermission &lt;server_ip&gt;:&lt;server port&gt; connect,resolve)

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

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

                &lt;tomcat-home&gt;/webapps 并检查它是否可以通过http://&lt;server name&gt;:&lt;server port&gt;/crossdomain.xml 访问

                【讨论】:

                  猜你喜欢
                  • 2012-11-27
                  • 2015-06-30
                  • 2011-07-26
                  • 2015-08-13
                  • 2018-12-26
                  • 2020-07-04
                  • 1970-01-01
                  • 2020-11-22
                  • 2014-06-22
                  相关资源
                  最近更新 更多