Java 8中的新java.security.AccessControlException

以前工作的网络代码将java.security.AccessControlException抛入一个完全沙盒化的Java applet

 Can't get socket 2255: java.security.AccessControlException: access denied ("java.net.SocketPermission" "50.31.1.13:2255" "connect,resolve") 

Oracle改变了什么 – 必须跳出哪些新的安全箍以保持套接字工作?

这在Java 1.7.0_55和所有以前版本的java中都有效。

这确实发生了变化……来自文档

http://docs.oracle.com/javase/8/docs/technotes/guides/jweb/enhancements-8.html

  • 对于沙盒RIA, URLPermission现在用于允许连接返回到启动它们的服务器。 URLPermissions基于代码源的协议,主机和端口授予。 此更改具有以下含义:

    • 对于沙盒RIA,不再授予源主机的SocketPermissions 。 从JDK 8开始,不会从JavaScript代码到RIA的调用被授予SocketPermissions

换句话说,您无法再在沙箱中创建新的Socket 。 您只能使用与完全沙盒化的applet中的代码库相同的主机, 相同的端口相同的协议来创建URL

除非Oracle改变主意,否则沙盒applet无法解决这个问题(否则会导致整个安全概念被破坏)。

好吧,对我而言,听起来Oracle决定加强applet的安全性要求。 这是我在CodeRanch上发现的:

使SecurityManager接受与套接字相关的权限检查:

 System.getSecurityManager().checkPermission(new SocketPermission("50.31.1.13:2255", "accept, connect, listen")); //I used IP address from your exception 

现在,与线程相关的检查:

 System.getSecurityManager().checkPermission(new RuntimePermission("readerThread")); 

这些行应放在main()方法的开头。

需要做的第二件事是签署你的jar/war/ear文件。 首先,创建一个密钥库:

 keytool -genkey -alias philip -keystore keystore 

现在,将CA签名的信任库证书放入其中或创建自签名证书:

 keytool -selfcert -alias philip -keystore keystore 

最后,签署文件:

 jarsigner -keystore keystore -signedjar WhatYouWantTheSignedJarToBeNamed.jar ThePreviousJARYouCreated.jar philip 

实际上对于签名的JAR文件,与SecurityManager相关的魔法可能是一个开销,但在我看来,这两者都更安全。

另外请注意,有时您可能需要签署外部jar ,而不仅仅是applet所在的jar

在client.policy(对于应用程序客户端)中添加权限,或者在需要设置属性的应用程序的server.policy(对于Web模块)中添加权限。 默认情况下,应用程序仅具有属性的读取权限。

例如,要为codebase目录中的所有文件授予读/写权限,请将以下内容添加或附加到client.policy或server.policy:

grant codeBase“file:/…/ build / sparc_SunOS / sec / – ”{permission java.util.PropertyPermission“*”,“read,write”; };