【问题标题】:Why does my applet get a java.security.AccessControlException: access denied (java.net.SocketPermission ...), and how can I avoid it?为什么我的小程序会出现 java.security.AccessControlException: access denied (java.net.SocketPermission ...),我该如何避免呢?
【发布时间】:2010-11-12 22:40:25
【问题描述】:

我们不知道为什么我的客户端在 Safari 中遇到 Java 安全异常。有人可以帮忙吗?

在 Windows 上的 Safari 中可靠地发生异常。这涉及到一个Java 小程序。 Windows Vista 上的 Firefox 和 IE8 也会出现异常。

以下是重现的步骤:

  1. 在 Windows 上打开 Safari

  2. 点击这里:http://www.cengraving.com/s/item?itemId=CH003

  3. 点击“自定义”(在屏幕底部)

  4. “即时证明”页面加载后,点击“加入购物车”。

完整的堆栈跟踪:

java.security.AccessControlException: access denied (java.net.SocketPermission www.cengraving.com resolve)
    at java.security.AccessControlContext.checkPermission(Unknown Source)
    at java.security.AccessController.checkPermission(Unknown Source)
    at java.lang.SecurityManager.checkPermission(Unknown Source)
    at java.lang.SecurityManager.checkConnect(Unknown Source)
    at sun.plugin.security.ActivatorSecurityManager.checkConnect(Unknown Source)
    at java.net.InetAddress.getAllByName0(Unknown Source)
    at java.net.InetAddress.getAllByName(Unknown Source)
    at java.net.InetAddress.getAllByName(Unknown Source)
    at java.net.InetAddress.getByName(Unknown Source)
    at sun.net.www.http.HttpClient.New(Unknown Source)
    at sun.net.www.http.HttpClient.New(Unknown Source)
    at sun.net.www.protocol.http.HttpURLConnection.getNewHttpClient(Unknown Source)
    at sun.net.www.protocol.http.HttpURLConnection.plainConnect(Unknown Source)
    at sun.net.www.protocol.http.HttpURLConnection.connect(Unknown Source)
    at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(Unknown Source)
    at com.designapplet.a.f.a(Unknown Source)
    at com.designapplet.ui.c.a(Unknown Source)
    at com.designapplet.ui.c.for(Unknown Source)
    at com.designapplet.ui.DesignApplet.buy(Unknown Source)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at sun.plugin.javascript.JSInvoke.invoke(Unknown Source)
    at sun.reflect.GeneratedMethodAccessor2.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at sun.plugin.javascript.JSClassLoader.invoke(Unknown Source)
    at sun.plugin.liveconnect.PrivilegedCallMethodAction.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.plugin.liveconnect.SecureInvocation$2.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.plugin.liveconnect.SecureInvocation.CallMethod(Unknown Source)
java.net.MalformedURLException: no protocol: 
    at java.net.URL.<init>(Unknown Source)
    at java.net.URL.<init>(Unknown Source)
    at java.net.URL.<init>(Unknown Source)
    at sun.plugin.liveconnect.SecureInvocation.checkLiveConnectCaller(Unknown Source)
    at sun.plugin.liveconnect.SecureInvocation.access$000(Unknown Source)
    at sun.plugin.liveconnect.SecureInvocation$2.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.plugin.liveconnect.SecureInvocation.CallMethod(Unknown Source)
java.net.MalformedURLException: no protocol: 
    at java.net.URL.<init>(Unknown Source)
    at java.net.URL.<init>(Unknown Source)
    at java.net.URL.<init>(Unknown Source)
    at sun.plugin.liveconnect.SecureInvocation.checkLiveConnectCaller(Unknown Source)
    at sun.plugin.liveconnect.SecureInvocation.access$000(Unknown Source)
    at sun.plugin.liveconnect.SecureInvocation$2.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.plugin.liveconnect.SecureInvocation.CallMethod(Unknown Source)

【问题讨论】:

  • 从小程序访问套接字通常需要权限。但是,applet 可以“打电话回家”,连接到它们来源的服务器——这似乎是你的情况。我没有访问该页面,但从堆栈跟踪看来,该调用源自 JavaScript。这意味着 JavaScript 权限使情况更加复杂。这可能是一个 Safari 错误。您可以尝试将打开连接的 Java 小程序代码包装在 doPrivileged 块中,这可能会解决问题。
  • Windows Vista 上的 Firefox 和 IE8 也会出现异常...有什么线索吗?

标签: java exception safari applet


【解决方案1】:

您可以覆盖 SecurityManager 使用的默认安全策略文件。

1) 创建一个文本文件(例如applet.policy)

2) 授予小程序所有权限

  grant {
   permission java.security.AllPermission;
  };

3) 使用

运行小程序
-J-Djava.security.policy=applet.policy

【讨论】:

  • 这不只适用于在本地运行小程序吗?这似乎不适用于在远程用户计算机上的浏览器中运行的小程序,这似乎更有可能发生。
  • 这是一个很好的提示!对于在 Firefox 中使用 IcedTea 的用户,以下是如何在客户端设置此策略的指南:icedtea.classpath.org/wiki/IcedTea-Web-Custom-Policies
【解决方案2】:

我有同样的问题。并通过自签名小程序解决了这个问题......

使用了以下步骤,它成功了

javac AppletClass.java
jar cvf AppletClass.jar AppletClass.class
keytool -genkey -validity 3650 -keystore pKeyStore -alias keyName
keytool -selfcert -keystore pKeyStore -alias keyName-validity 3650
jarsigner -keystore pKeyStore AppletClass.jar keyName

只要回答它会问的问题,它就会完成工作

注意:我收到本地读/写文件的错误

【讨论】:

  • 谢谢,这是否发生在 IE 和 Firefox 上?还是只是野生动物园?以及哪个操作系统?
  • 我解决了这个问题。请查看解决方案。感谢您的帮助!
【解决方案3】:

我也有同样的问题! JavaScript 调用嵌入在同一文档中的小程序的公共方法。这应该触发小程序从“家”加载一些数据,因此应该打开与加载小程序的同一个域的连接 - 对于未签名的小程序也应该允许没有进一步的权限。

我也仅在 Safari(5.0.2 for Windows,JRE 1.6.0_22)中识别出此安全异常。 IE 和 FireFox 中的同一个小程序运行良好。

我也认为这是 Safari 的 Java Sandbox 中的一个错误。


编辑: 使用 doPrivileged 没有帮助,但我发现了这个解决方法: 如果您通过计时器事件将 JavaScript 调用与请求的执行“解耦”,则 Safari 在此处对游戏设置的安全限制将不再禁止执行。详细:

  • 从 JavaScript 调用的方法仅创建一个 javax.swing.Timer(用于安排一个事件,因此必须将重复属性设置为 false)。您可以将延迟设置得非常短(例如 50 毫秒)。
  • 必须将要调用的方法调用放入计时器调用的 ActionEvent 侦听器 (actionPerformed) 中。

可能会使事情变得更复杂的一个问题是,在 actionPerformed 上下文中,只能访问静态变量。如果 JavaScript 调用包含变量,则必须由最初调用的方法将这些变量放入静态“缓冲区”变量中,之后调度的事件可以从中读取值。

在我的测试中,只有 javax.swing.Timer 提供了所需的解耦,而 java.util.Timer 不能用于此目的。

【讨论】:

  • Windows Vista 上的 Firefox 和 IE8 也会出现异常...有什么线索吗?
  • 我解决了这个问题。请查看解决方案。感谢您的帮助!
【解决方案4】:

感谢您的回复。我没有奖励赏金,因为虽然答案都很有帮助,但没有一个能完全解决问题。

最终,我通过将数据从小程序传递到网页,然后执行 AJAX 调用与服务器通信来解决了这个问题。当然,这不是最优雅的解决方案,但到目前为止它已被证明是有效的。

试一试,让我知道它是否适合你。

再次感谢!

【讨论】:

    【解决方案5】:

    这是一个小程序吗?如果是,您需要为您的小程序签名以访问套接字,(这似乎是您正在做的......)

    查看这里了解更多信息:

    http://java.sun.com/developer/onlineTraining/Programming/JDCBook/signed.html

    【讨论】:

    • 是的,这是一个小程序。你知道为什么这个问题出现在 safari 而不是其他浏览器吗?
    • 这发生在所有平台上的所有浏览器中。它是 Java 的一部分。
    • 这并不完全正确;即使是未签名的小程序也可以连接到它们所来自的主机。
    【解决方案6】:

    在 Linux 上它可以工作。

    Add to cart按钮执行功能

      function saveLayout() {
    
        showSaveMsg();
        var status = document.app.buy();
        var loc = "http://www.cengraving.com/s/cart";
    
        if (status == 'GOOD') {
          window.location = getCartUrl();
        } else {
          showErrorMsg(status);
        }
      } 
    

    一些备注:

    • 本地变量loc是在app调用后定义的,反正没有使用,这正常吗?

    • 另外,try catch 可能会有所帮助(在 Javascript 中,包装 app.buy() 调用)。

    • 此外,我在网上做了一些研究,有些人 - 有同样的错误,但用法不同 - 报告了ClassPath 问题。您是否有任何具体情况可能会阻止相关 JRE 被使用?

    【讨论】:

    • 谢谢,ring0。没有看到多余的“loc”变量。当您说阻止相关 JRE 被使用时,您是什么意思?这个错误非常神秘。我希望我可以购买代表点并吸引更广泛的受众来解决问题。
    • 嗨 ring0 ...您看到我发布的解决方案了吗?再次感谢您指出多余的“loc”变量。
    【解决方案7】:

    它表现为一个安全异常,但问题确实是一个错误的 URL。如果您遵循堆栈,您会看到有一个 MalformedURLException。

    这很可能是由于在某个需要 URL 的地方传递了一个 URI。通过 LiveConnect API 从外观上看。我猜它没有找到预期的主机名,并且正在尝试连接到默认值,可能是 localhost。 SecurityManager 不允许这样做,因此会出现 SecurityException。

    在 href 中,您可以使用 URI(例如,HREF="/somepath"),因为浏览器会根据页面本身的 URL 解析它以生成完整的 URL(例如,http://example.com/somepath)。

    您可以在 Java 中使用 [适当的 URL 构造函数][1] 来执行此操作。

    更新: 啊,我看错了;我认为这是一个单一的堆栈跟踪。

    曾经有一个 bug,liveconnect 可以访问 jar: url 并获得任意套接字连接。对此的修复可能会导致从 liveconnect 线程打开 url 连接的问题。如果在buy 方法中,你启动一个线程来执行连接会发生什么?

    [1]:http://download.oracle.com/javase/6/docs/api/java/net/URL.html#URL(java.net.URL,java.lang.String)

    【讨论】:

    • 但是 MalformedURLException 发生在堆栈跟踪的后面。可能是因为第一个异常破坏了小程序逻辑中的某些内容。 AccessControlException 明确表示没有解析 www.cengraving.com 的权限。这是小程序所在的位置,这真的很奇怪。
    • 德文?对 Sergey 的 cmets 有什么想法?
    【解决方案8】:

    JRE 沙盒试图阻止源自 javascript 的方法调用来做有害的事情,但它所做的只是让程序员的生活更加艰难。

    我发现的最佳解决方法是构建一个生产者和消费者设计模式事件队列,它在 JavaScript 发起的调用和实际的“脏工作”之间实现非常松散的耦合。

    真正糟糕的是,在 XP 或 Win7 中运行良好的代码在 Vista 中可能会抛出异常。

    【讨论】:

    • 我们认为我们解决了这个问题。请查看我们的解决方案。它也应该适用于 Vista。
    猜你喜欢
    • 1970-01-01
    • 2012-04-08
    • 2019-07-04
    • 1970-01-01
    • 2015-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多