为什么我的小程序会出现 java.security.AccessControlException: 访问被拒绝 (java.net.SocketPermission ...),如何避免它?
我们不知道为什么我的客户在 Safari 中遇到 Java 安全异常。有人可以帮忙吗?
该异常在 Windows 上的 Safari 中可靠发生。这涉及到一个Java applet。 Windows Vista 上的 Firefox 和 IE8 也会出现此异常。
以下是重现步骤:
在 Windows 上打开 Safari
点击“自定义”(位于屏幕底部)
“即时证明”页面加载后,单击“添加到购物车”。
完整的堆栈跟踪:
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)
We are clueless about why my client is encountering a Java Security exception in Safari. Could anyone help?
The exception occurs reliably in Safari on Windows. This involves a Java applet. The exception also occurs with Firefox and IE8 on Windows Vista.
Here are the steps to reproduce:
Open Safari on Windows
Click here: http://www.cengraving.com/s/item?itemId=CH003
Click "Customize" (at bottom of screen)
After the "Instant Proof" page loads, click "Add to cart."
Full stack trace:
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)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
您可以覆盖 SecurityManager 使用的默认安全策略文件。
1) 创建一个文本文件(例如 applet.policy)
2) 授予小程序所有权限
3) 运行小程序
You can override the default security policy file used by the SecurityManager.
1) Create a text file (eg. applet.policy)
2) Grant all permissions to the applet
3) Run the applet with
我有同样的问题。并通过自签名小程序解决了这个问题...
使用了以下步骤,它
只需回答它会提出的问题即可完成工作
注意:我收到本地读/写文件的错误
i had the same problem. And solved this by self signing the applet...
used the following steps and it worked
just answer the questions it will ask and it will do the work
NOTE : i was getting the error for local read/write file
我有同样的问题! JavaScript 调用嵌入同一文档中的小程序的公共方法。这应该触发小程序从“home”加载一些数据,因此应该打开到加载小程序的同一域的连接 - 这对于没有进一步权限的未签名小程序也应该允许。
我还仅在 Safari(Windows 为 5.0.2,JRE 1.6.0_22)中认识到此安全异常。同样的小程序在 IE 和 FireFox 中表现良好。
我还相信这是 Safari 的 Java Sandbox 中的一个错误。
编辑:
使用 doPrivileged 没有帮助,但我发现了这个解决方法:
如果您通过计时器事件将 JavaScript 调用与请求的执行“解耦”,则 Safari 在此游戏中添加的安全限制将不再禁止执行。详细来说:
一个可能使事情变得更加复杂的问题是,在 actionPerformed 上下文中只能访问静态变量。如果 JavaScript 调用包含变量,则必须通过最初调用的方法将这些变量放入静态“缓冲区”变量中,计划事件随后可以从中读取值。
在我的测试中,只有 javax.swing.Timer 提供了所需的解耦,而 java.util.Timer 不能用于此目的。
I have the same problem! JavaScript calls a public method of an applet that is embedded in the same document. This should trigger that the applet loads some data from "home", so the connection should be opened to the same domain from where the applet was loaded - which should be allowed also for unsigned applets without further privileges.
I also recognized this security exception only with Safari (5.0.2 for Windows, JRE 1.6.0_22). The same applet in IE and FireFox is doing well.
I also believe that this is a bug in the Java Sandbox of Safari.
EDIT:
Using doPrivileged did not help but I found this workaround:
If you "decouple" the JavaScript call from the requested execution through a timer event, the execution will no longer be prohibited by the security restriction that Safari puts into the game here. In detail:
One problem that might make things a bit more complicated is that in the actionPerformed context only static variables are accessible. If the JavaScript call contains variables, these must be put by the initially called method into a staic "buffer" variable from which the scheduled event can read the value afterwards.
In my tests only the javax.swing.Timer provided the required decoupling whereas java.util.Timer could not be used for that purpose.
感谢您的回复。我没有授予赏金,因为虽然答案都很有帮助,但没有一个能完全解决问题。
最终,我通过将数据从小程序传递到网页,然后执行 AJAX 调用与服务器通信来解决了问题。当然,这不是最优雅的解决方案,但迄今为止它已被证明是有效的。
尝试一下,让我知道它是否适合你。
再次感谢!
Thanks for the responses. I didn't award the bounty because while the answers were all helpful, none quite solved the problem.
Ultimately, I solved the problem by passing the data from the applet to the web page, then executing an AJAX call to communicate with the server. Not the most elegant solution, certainly, but it has proved effective thus far.
Try it out, and lemme know if it works for you.
Thanks again!
这是一个小程序吗?如果是,您需要对您的小程序进行签名才能访问套接字(这似乎就是您正在做的事情...)
请参阅此处以获取更多信息:
http://java.sun.com/developer/onlineTraining/Programming/JDCBook/signed.html
Is this an applet? If it is, you need to sign your applet for it to access a socket, (which seems to be what you are doing...)
See here for more information:
http://java.sun.com/developer/onlineTraining/Programming/JDCBook/signed.html
在 Linux 上它可以工作。
添加到购物车
按钮执行该函数一些备注:
本地变量
loc
在应用程序调用后定义并且无论如何都没有使用,这正常吗?try
catch
可能会有所帮助(在 Javascript 中,包装app.buy()
调用)。此外,我在网上做了一些研究,有些人 - 遇到相同的错误但使用不同 - 报告了
ClassPath
问题。您是否有任何特定的内容可以阻止相关 JRE 的使用?On Linux it works.
The
Add to cart
button executes the functionSome remarks:
Is it normal that the local var
loc
is defined after the app call and not used anyway?Also, a
try
catch
may help (in Javascript, wrapping theapp.buy()
call).Besides, I did a bit of research on the Net, and some people - having the same error but from a different usage - report a
ClassPath
problem. Do you have anything specific that could prevent the relevant JRE to be utilized?它表现为安全异常,但问题实际上是一个错误的 URL。如果您跟踪堆栈,您将看到存在 MalformedURLException。
这很可能是由于在需要 URL 的地方传递了 URI 造成的。从表面上看是通过LiveConnect API。我猜它没有找到预期的主机名,并且正在尝试连接到默认主机名,可能是本地主机。 SecurityManager 不允许这样做,因此会出现 SecurityException。
在 href 中,您可以使用 URI(例如,HREF="/somepath"),因为浏览器会根据页面本身的 URL 解析它,以生成完整的 URL(例如,http://example.com/somepath)。
您可以在 Java 中使用 [适当的 URL 构造函数][1] 来完成此操作。
更新:
啊,我看错了;我认为那是一个堆栈跟踪。
曾经存在一个错误,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)
It's manifesting as a security exception, but the problem is really a bad URL. If you follow the stack, you'll see there is a MalformedURLException.
This is most likely caused by passing a URI somewhere that was expecting a URL. Through the LiveConnect API from the looks of it. I'd guess it's not finding a host name where one is expected, and is trying to connect to a default, probably localhost. That's disallowed bye the SecurityManager hence the SecurityException.
In href's you can use URI (e.g., HREF="/somepath") because the browser resolves that against the URL for the page itself to produce the a full URL (e.g., http://example.com/somepath).
You can do that in Java by using the [appropriate URL constructor][1].
Update:
Ah, I misread; I thought that was a single stack trace.
There used to be a bug where liveconnect could access a jar: url and obtain an arbitrary socket connection. The fix for that might be causing an issue with opening url connections from the liveconnect thread. What happens, if in the
buy
method, you start a thread to perform the connection?[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 中可能会抛出异常。
JRE sandbox tries to prevent javascript originated method calls to do harmful things but only thing it does is making programmers life harder.
Best workaround I've found to this is to build a producer & consumer design pattern event queue which implements very loose coupling between javascript originated calls and actual "dirty work".
What really sucks is that a code which runs fine in XP or Win7 may throw exception in Vista.