代码之家  ›  专栏  ›  技术社区  ›  Crashalot

为什么我的applet会得到java.security.AccessControlException:access denied(java.net.SocketPermission…),如何避免?

  •  17
  • Crashalot  · 技术社区  · 14 年前

    我们不知道为什么我的客户机在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)
    
    8 回复  |  直到 14 年前
        1
  •  16
  •   competent_tech    13 年前

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

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

    2) 授予小程序所有权限

      grant {
       permission java.security.AllPermission;
      };
    

    3) 使用运行小程序

    -J-Djava.security.policy=applet.policy
    
        2
  •  9
  •   Varun    14 年前

    我也有同样的问题。通过自签名applet解决了这个问题。。。

    使用了以下步骤

    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
    

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

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

        3
  •  4
  •   Hacky    14 年前

    我也有同样的问题!JavaScript调用嵌入在同一文档中的applet的公共方法。这将触发applet从“home”加载一些数据,因此应该打开到加载applet的同一域的连接-这也应该允许未签名的applet没有进一步的特权。

    我也只在Safari(5.0.2 for Windows,JRE 1.6.0_22)中发现了这个安全异常。同样的applet在IE和FireFox中运行良好。

    我也相信这是Safari的Java沙盒中的一个bug。


    编辑: 使用doPrivileged没有帮助,但我找到了解决方法: 如果通过计时器事件将JavaScript调用与请求的执行“分离”,那么Safari在游戏中设置的安全限制将不再禁止执行。详细说明:

    • 从JavaScript调用的方法只创建javax.swing.Timer(以调度一个事件,因此repeat属性必须设置为false)。您可以将延迟设置得很短(例如50毫秒)。
    • 要调用的方法调用必须放入由计时器调用的ActionEvent侦听器(actionPerformed)。

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

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

        4
  •  2
  •   Crashalot    14 年前

    谢谢你的回复。我没有赏金,因为虽然答案都是有用的,但没有一个能完全解决问题。

    最终,我通过将数据从applet传递到web页面,然后执行AJAX调用与服务器通信来解决了这个问题。当然,这不是最优雅的解决方案,但迄今已证明是有效的。

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

    再次感谢!

        5
  •  0
  •   Starkey    14 年前

    这是小程序吗?如果是的话,你需要在applet上签名,让它访问一个socket(这似乎是你正在做的…)

    有关详细信息,请参见此处:

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

        6
  •  0
  •   Déjà vu    14 年前

    在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 在应用程序调用后定义,但仍不使用?

    • 还有,一个 try catch 可能有帮助(在Javascript中,包装 app.buy() 呼叫)。

    • 此外,我在网上做了一些研究,有些人——有同样的错误,但来自不同的用法——报告 ClassPath 问题。您是否有任何特定的东西可以阻止使用相关的JRE?

        7
  •  0
  •   Devon_C_Miller    14 年前

    它显示为一个安全异常,但问题实际上是一个糟糕的URL。如果跟踪堆栈,您将看到有一个格式错误的异常。

    这很可能是由于将URI传递到了某个需要URL的地方而导致的。通过LiveConnect API从外观上看。我猜它找不到预期的主机名,而是试图连接到默认的,可能是本地主机。安全管理器不允许这样做,因此出现了安全异常。

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

    在Java中,您可以使用[适当的URL构造函数][1]来实现这一点。

    更新: 啊,我看错了;我以为那是一个堆栈跟踪。

    liveconnect曾经有一个bug,它可以访问jar:url并获得任意的套接字连接。对此的修复可能导致从liveconnect线程打开url连接时出现问题。如果在 buy 方法,是否启动线程来执行连接?

    [1] 以下内容: http://download.oracle.com/javase/6/docs/api/java/net/URL.html#URL(java.net.URL ,java.lang.字符串)

        8
  •  0
  •   Hasa    14 年前

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

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

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