简体   繁体   中英

“java.security.AccessControlException: access denied” executing a signed Java Applet

I have a little Java Applet and I have an annoying issue. I have signed my JAR with my own keystore using jarsigner tool (following these instructions ).

The Java Applet downloads a signed JAR and tries to launch it with an extended class of URLClassLoader . This JAR tries to execute this line of code:

ClassLoader.getSystemClassLoader().getResource("aResource");

It fails with a large stack trace finished by:

Caused by: java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "getClassLoader")
    at java.security.AccessControlContext.checkPermission(AccessControlContext.java:366)
    at java.security.AccessController.checkPermission(AccessController.java:555)
    at java.lang.SecurityManager.checkPermission(SecurityManager.java:549)
    at java.lang.ClassLoader.getSystemClassLoader(ClassLoader.java:1476)
    at test.SecondJAR.main(SecondJAR.java:8)

(Line 8 of test.SecondJAR corresponds to getResource(...) method

When the Java Applet is launched, the user is prompted to accept the certificate if he/she trusts the publisher:

给用户的消息

Even if I accept it, the exception occurred. Even if I install the certificate, and the prompt message is automatically accepted, the exception occurred.

I have tried too this:

AccessController.doPrivileged(new PrivilegedAction<Object>() {
    public Object run() {
        ClassLoader.getSystemClassLoader().getResource("aResource");
        return null;
    }
});

And it fails with the same exception.

Any help would be appreciated!

Finally I have found the answer!

I followed the guidelines of Andrew Thomson and I created a custom SecurityManager . My little security manager looks like this:

private class MySecurityManager extends SecurityManager {
    @Override
    public void checkPermission(Permission perm) {
        return;
    }
}

It is a neglected security manager that accepts all permissions. It should be improved allowing only getting system ClassLoader in runtime.

To use my ugly SecurityManager I added these lines at the beginning of Java Applet start() method:

SecurityManager sm = new MySecurityManager();
System.setSecurityManager(sm);

With this workaround, all the process worked as expected!

Maybe there exist other (better) solutions, but it worked for me.

Thank you all!

The problem is that the JRE only considers code in the original code-base to be trusted. Two possible solutions are:

  1. Set a custom security manager that allows the new code to have the privileges it requires.
  2. Wrap the new code in a PrivilegedAction & call it from AccessController.doPrivileged(..) method (just occurred to me as a possibility, not sure if I understand the scope of it, completely untested).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM