문제

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:

Message to the user

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).
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top