为什么我的applet得到java.security.AccessControlException:访问被拒绝(java.net.SocketPermission …),我该如何避免它?

我们对我的客户端在Safari中遇到Java安全性exception的原因一无所知。 有人可以帮忙吗?

在Windows上的Safari中可靠地发生exception。 这涉及Java applet。 Windows Vista上的Firefox和IE8也会出现exception。

以下是重现的步骤:

  1. 在Windows上打开Safari

  2. 点击此处: http : //www.cengraving.com/s/item?icmId = CH003

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

  4. 加载“Instant Proof”页面后,单击“添加到购物车”。

完整堆栈跟踪:

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.afa(Unknown Source) at com.designapplet.ui.ca(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.(Unknown Source) at java.net.URL.(Unknown Source) at java.net.URL.(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.(Unknown Source) at java.net.URL.(Unknown Source) at java.net.URL.(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) 

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

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

2)授予applet的所有权限

  grant { permission java.security.AllPermission; }; 

3)运行applet

 -J-Djava.security.policy=applet.policy 

我有同样的问题。 并通过自我签署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 

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

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

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

我也只用Safari(5.0.2 for Windows,JRE 1.6.0_22)识别出这个安全例外。 IE和FireFox中的相同applet运行良好。

我也相信这是Safari的Java沙箱中的一个错误。


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

  • 从JavaScript调用的方法只创建一个javax.swing.Timer(计划一个事件,因此必须将repeat-property设置为false)。 您可以将延迟设置得非常短(例如50 ms)。
  • 要调用的方法调用必须放入由定时器调用的ActionEvent侦听器(actionPerformed)中。

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

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

谢谢你的回复。 我没有奖励赏金,因为尽管答案都很有帮助,但没有人能解决问题。

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

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

再次感谢!

这是一个小程序吗? 如果是,你需要签署你的小程序,以便它访问套接字,(这似乎是你正在做的……)

浏览此处获取更多信息:

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

在Linux上它工作。

Add to cart按钮执行该function

  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); } } 

一些评论:

  • 在应用程序调用之后定义了本地var loc并且仍未使用它是正常的吗?

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

  • 此外,我对网络进行了一些研究,有些人 – 具有相同的错误,但来自不同的用途 – 报告了一个ClassPath问题。 您是否有任何可能妨碍相关JRE使用的具体内容?

它表现为一个安全例外,但问题实际上是一个糟糕的URL。 如果你跟着堆栈,你会看到有一个MalformedURLException。

这很可能是因为在某个期望URL的地方传递了一个URI。 通过LiveConnect API从它的外观。 我猜它没有找到一个预期的主机名,并且正在尝试连接到默认的,可能是localhost。 因为SecurityManager不允许使用SecurityException。

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

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

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

曾经有一个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)

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

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

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