New java.security.AccessControlException in Java 8

2020-01-29 02:41发布

问题:

Previously working network code is throwing java.security.AccessControlException in a fully sandboxed Java applet.

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

What has Oracle changed - what new security hoop must be jumped to keep sockets to working?

This worked/works in Java 1.7.0_55 and all previous versions of java.

回答1:

This has indeed changed… From the documentation

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

  • For sandbox RIAs, URLPermission is now used to allow connections back to the server from which they were started. URLPermissions is granted based on protocol, host and port of the code source. This change has the following implications:

    • For sandbox RIAs, SocketPermissions for the origin host is no longer granted. Calls from JavaScript code to the RIA are not granted SocketPermissions beginning with JDK 8.

In other words, you cannot create a new Socket in a sandbox anymore. You can only create a URL using the same host, same port, and same protocol as the codebase from a fully sandboxed applet then.

Unless Oracle changes its mind, there is no way for a sandboxed applet to get around this (otherwise it would render the entire security concept broken).



回答2:

Well, for me it sounds like Oracle decided to strengthen the applets security requirements. Here is what I found on CodeRanch:

Make SecurityManager accept socket-related permission checks:

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

Now, thread-related checks:

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

These lines should be put in the beginning of main() method.

The second thing needs to be done is signing your jar/war/ear file. First, create a keystore:

keytool -genkey -alias philip -keystore keystore  

Now, put the signed by CA in your truststore certificate to it or create self-signed certificate:

keytool -selfcert -alias philip -keystore keystore 

And finally, sign the file:

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

Actually for signed JAR file the SecurityManager-related magic might be an overhead, but in my opinion it is safer to do both.

Also be advised that sometimes you may need to sign external jars, not only the jar where your applet resides.



回答3:

Add the permission in client.policy (for the application client), or in server.policy (for web modules) for the application that needs to set the property. By default, applications only have read permission for properties.

For example, to grant read/write permission for all files in the codebase directory, add or append the following to client.policy or server.policy:

grant codeBase "file:/.../build/sparc_SunOS/sec/-" { permission java.util.PropertyPermission "*", "read,write"; };