我在使用 Java Web Start 时遇到了一个严重的问题,我无法理解。情况如下:我有一个 JavaFX 应用程序,编写为 Java8,我想使用 Java WebStart 进行部署。直到最近,我还使用 HTTP 与服务器进行通信,一切都运行良好。我可以使用浏览器中嵌入的 Web Start 或作为独立应用程序来部署该应用程序。
不过,我现在已将通信更改为使用 WebSockets。为此,我目前正在使用 tyrus 实现。现在问题来了:由于我添加了 tyrus 库,当 tyrus 尝试访问系统属性时,我总是收到 AccessControlException:
Caused by: java.security.AccessControlException: access denied ("java.util.PropertyPermission" "weblogic.websocket.client.max-aio-threads" "read")
at java.security.AccessControlContext.checkPermission(Unknown Source) ~[na:1.8.0_25]
at java.security.AccessController.checkPermission(Unknown Source) ~[na:1.8.0_25]
at java.lang.SecurityManager.checkPermission(Unknown Source) ~[na:1.8.0_25]
at sun.plugin2.applet.FXAppletSecurityManager.checkPermission(Unknown Source) ~[na:na]
at java.lang.SecurityManager.checkPropertyAccess(Unknown Source) ~[na:1.8.0_25]
at java.lang.System.getProperty(Unknown Source) ~[na:1.8.0_25]
at org.glassfish.tyrus.container.jdk.client.JdkClientContainer.openClientSocket(JdkClientContainer.java:106) ~[na:na]
但是,我可以轻松地从我自己的任何类中访问该属性,例如如果我这样做
logger.info(System.setProperty(ClientManager.WLS_MAX_THREADS, "1"));
logger.info(System.getProperty(ClientManager.WLS_MAX_THREADS));
我得到了预期的结果,没有安全问题。
当然,我已经确保所有罐子都经过完全签名,所有罐子都有Permissions: all-permissions
在其 Manifest.MF 文件中标记,并且 jnlp 确实具有所需的<security><all-permissions /></security>
tag.
除此之外,我还尝试使用 jetty websocket 实现,但这给了我完全相同的问题。
那么有人知道为什么 tyrus 代码无法访问与主代码相同的系统属性吗?
好的,谢谢您的帮助,我终于找到答案了。 @Tom Hawtin 的提示给了我正确的线索,我仍然需要将通话结束webSocket.connectToClient()
in AccessController.doPrivileged()
获得依赖代码的完整权限。
但是我仍然不完全理解为什么用签名代码Permissions: all-permissions
不可信,也许我应该阅读 WebStart 安全模型。
编辑:
好吧,经过更多尝试并发现更多奇怪的错误后,我发现了真正的问题:当我将 WebSocket 集成到应用程序中时,我大量使用了CompleableFuture.xxxAsync()
方法。默认情况下,它们在公共 ForkJoinPool 上运行,而 ForkJoinPool 又在特殊线程上运行(InnocuousForkJoinWorkerThread
)如果存在安全管理器(使用 jnpl 的情况很明显)。这些没有任何权限,这正确地触发了所有这些错误。
所以解决方案是使用自定义的 ExecutorxxxAsync(xxx, executor)
calls.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)