为什么我的小程序会出现 java.security.AccessControlException: access denied (java.net.SocketPermission ...),我该如何避免它?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4169717/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why does my applet get a java.security.AccessControlException: access denied (java.net.SocketPermission ...), and how can I avoid it?
提问by Crashalot
We are clueless about why my client is encountering a Java Security exception in Safari. Could anyone help?
我们不知道为什么我的客户在 Safari 中遇到 Java 安全异常。有人可以帮忙吗?
The exception occurs reliably in Safari on Windows. This involves a Java applet. The exception also occurs with Firefox and IE8 on Windows Vista.
该异常在 Windows 上的 Safari 中可靠地发生。这涉及到一个 Java 小程序。Windows Vista 上的 Firefox 和 IE8 也会出现异常。
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."
在 Windows 上打开 Safari
单击“自定义”(在屏幕底部)
加载“即时证明”页面后,单击“添加到购物车”。
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.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.accessjavac 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
0(Unknown Source)
at sun.plugin.liveconnect.SecureInvocation.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 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);
}
}
0(Unknown Source)
at sun.plugin.liveconnect.SecureInvocation.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at sun.plugin.liveconnect.SecureInvocation.CallMethod(Unknown Source)
采纳答案by Crashalot
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.
最终,我通过将数据从小程序传递到网页,然后执行 AJAX 调用与服务器通信来解决问题。当然,这不是最优雅的解决方案,但迄今为止它已被证明是有效的。
Try it out, and lemme know if it works for you.
试试看,让我知道它是否适合你。
Thanks again!
再次感谢!
回答by Starkey
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
http://java.sun.com/developer/onlineTraining/Programming/JDCBook/signed.html
回答by Hacky
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.
我也有同样的问题!JavaScript 调用嵌入在同一文档中的小程序的公共方法。这应该会触发小程序从“home”加载一些数据,因此应该从加载小程序的同一个域打开连接——这也应该被允许用于没有进一步特权的未签名小程序。
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.
我也仅在 Safari(Windows 5.0.2,JRE 1.6.0_22)中识别出此安全异常。同一个小程序在 IE 和 FireFox 中运行良好。
I also believe that this is a bug in the Java Sandbox of Safari.
我也认为这是 Safari 的 Java Sandbox 中的一个错误。
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:
编辑:使用 doPrivileged 并没有帮助,但我找到了这个解决方法:如果您通过计时器事件将 JavaScript 调用与请求的执行“分离”,则 Safari 在这里放入游戏的安全限制将不再禁止执行。详细:
- the method that is called from JavaScript only creates a javax.swing.Timer (to schedule one event so the repeat-property must be set false). You can set the delay quite short (e.g. 50 ms).
- The method call that is intended to be called has to be put into the ActionEvent listener (actionPerformed) which is called by the timer.
- 从 JavaScript 调用的方法只创建一个 javax.swing.Timer(为了安排一个事件,所以必须将重复属性设置为 false)。您可以将延迟设置得非常短(例如 50 毫秒)。
- 要调用的方法调用必须放入计时器调用的 ActionEvent 侦听器 (actionPerformed) 中。
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.
一个可能使事情变得更复杂的问题是,在 actionPerformed 上下文中,只能访问静态变量。如果 JavaScript 调用包含变量,则这些变量必须由最初调用的方法放入静态“缓冲区”变量中,计划事件之后可以从中读取值。
In my tests only the javax.swing.Timer provided the required decoupling whereas java.util.Timer could not be used for that purpose.
在我的测试中,只有 javax.swing.Timer 提供了所需的解耦,而 java.util.Timer 不能用于该目的。
回答by Devon_C_Miller
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.
它表现为安全异常,但问题确实是一个错误的 URL。如果您按照堆栈进行操作,您会看到有一个 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.
这很可能是由于将 URI 传递到需要 URL 的地方造成的。从它的外观通过 LiveConnect API。我猜它没有找到预期的主机名,而是试图连接到默认的,可能是本地主机。这在 SecurityManager 中是不允许的,因此是 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).
在 href 中,您可以使用 URI(例如,HREF="/somepath"),因为浏览器会根据页面本身的 URL 进行解析以生成完整的 URL(例如,http: //example.com/somepath)。
You can do that in Java by using the [appropriate URL constructor][1].
您可以通过使用 [适当的 URL 构造函数][1] 在 Java 中做到这一点。
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?
曾经有一个 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)
[1]:http: //download.oracle.com/javase/6/docs/api/java/net/URL.html#URL(java.net.URL, java.lang.String)
回答by Varun
i had the same problem. And solved this by self signing the applet...
我有同样的问题。并通过自签名小程序解决了这个问题......
used the following steps and it worked
使用了以下步骤并且它起作用了
grant {
permission java.security.AllPermission;
};
just answer the questions it will ask and it will do the work
只需回答它会提出的问题,它就会完成工作
NOTE : i was getting the error for local read/write file
注意:我收到本地读/写文件的错误
回答by e2-e4
On Linux it works.
在 Linux 上它可以工作。
The Add to cart
button executes the function
该Add to cart
按钮执行功能
-J-Djava.security.policy=applet.policy
Some 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?
loc
在应用程序调用之后定义本地变量并且无论如何都不使用是否正常?此外, a
try
catch
可能会有所帮助(在 Javascript 中,包装app.buy()
调用)。此外,我在网络上做了一些研究,有些人 - 有相同的错误但使用不同 - 报告了一个
ClassPath
问题。您是否有任何可能阻止使用相关 JRE 的具体情况?
回答by Hasa
JRE sandbox tries to prevent javascript originated method calls to do harmful things but only thing it does is making programmers life harder.
JRE 沙箱试图阻止由 javascript 发起的方法调用来做有害的事情,但它唯一做的就是让程序员的生活更加艰难。
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".
我发现的最佳解决方法是构建一个生产者和消费者设计模式事件队列,它在 javascript 发起的调用和实际的“脏工作”之间实现非常松散的耦合。
What really sucks is that a code which runs fine in XP or Win7 may throw exception in Vista.
真正糟糕的是,在 XP 或 Win7 中运行良好的代码可能会在 Vista 中抛出异常。
回答by Seb74
You can override the default security policy file used by the SecurityManager.
您可以覆盖 SecurityManager 使用的默认安全策略文件。
1) Create a text file (eg. applet.policy)
1)创建一个文本文件(例如applet.policy)
2) Grant all permissions to the applet
2)授予小程序所有权限
##代码##3) Run the applet with
3)运行小程序
##代码##