“java.security.AccessControlException:access denied”执行签名的Java Applet

时间:2012-07-03 08:31:59

标签: java security browser applet accesscontrolexception

我有一个小Java小程序,我有一个恼人的问题。我使用jarsigner工具使用我自己的密钥库签名我的JAR(遵循这些instructions)。

Java Applet下载签名 JAR并尝试使用扩展类URLClassLoader启动它。这个JAR试图执行这行代码:

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

它失败了,堆栈跟踪很大,完成了:

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)

(test.SecondJAR的第8行对应getResource(...)方法

启动Java Applet时,如果用户信任发布者,则会提示用户接受证书:

Message to the user

即使我接受它,也会发生异常。即使我安装了证书,并且自动接受了提示消息,也会发生异常。

我也尝过这个:

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

它以相同的例外失败。

任何帮助将不胜感激!

2 个答案:

答案 0 :(得分:8)

最后我找到了答案!

我遵循了Andrew Thomson的指南,并创建了自定义SecurityManager。我的小安全经理看起来像这样:

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

这是一个被忽视的安全管理器,它接受所有权限。应该进行改进,只允许在运行时获取系统ClassLoader。

要使用我丑陋的SecurityManager,我在Java Applet start()方法的开头添加了这些行:

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

通过此解决方法,所有过程都按预期工作!

也许存在其他(更好的)解决方案,但它对我有用。

谢谢大家!

答案 1 :(得分:2)

问题是JRE只考虑原始代码库中的代码。两种可能的解决方案是:

  1. 设置自定义安全管理器,允许新代码具有所需的权限。
  2. 将新代码换入PrivilegedAction&amp;从AccessController.doPrivileged(..)方法调用它(我发现这是一种可能性,不确定我是否理解它的范围,完全未经测试)。