【发布时间】:2016-10-11 09:32:27
【问题描述】:
您好 SecurityManager 专家 ;-)
我编写了一个小型插件框架,它使用单独的隔离类加载器加载插件。要成功取消部署插件,重要的是确保应用程序不持有对插件类加载器加载的类的引用。
Java 中有一个称为shutdown hook 的功能,它使客户端代码能够注册一个线程,该线程在JVM 被请求关闭时执行。这意味着可能会有 JVM 持有对插件类加载器加载的类的引用。
我的第一次尝试是安装一个拒绝添加关闭挂钩的 SecurityManager。这完全有效,并且拒绝了所有添加关闭挂钩的尝试。有趣的是,我意识到并不是插件本身想要添加关闭挂钩。该插件只是通过加载字体来触发 AWT/Swing 内部(精确:SunFontManager)。 SunFontManager 反过来添加了关闭钩子,以便在 JVM 退出时进行一些内部处理。我不想否认插件加载了字体(因为它必须),我不想否认 Java 内部添加他们的东西。
对我来说,似乎我必须授予代码更多的权限(如果 sun.*|java.*|javax.* 包在堆栈跟踪中..uuuhmm...ugly),而不是正常情况下。但这打破了安全框架的约定,它假定客户端代码不能比调用它的代码拥有更多的权限。
我如何区分不是插件代码而是Java内部想要做某事?或者有没有其他方法可以确保不通过否认来破坏内部?
发生情况的示例
为了让事情更清楚,这是我的应用程序中实际发生的情况。我安装了一个自定义的 SecurityManager,它应该拒绝由插件直接执行的addShutdownHook,但如果作为 Java 内部类的副作用执行,则不应拒绝这些调用。
SecurityManager 是使用 System.setSecurityManager() 安装的,并且这样做:
@Override
public void checkPermission(java.security.Permission perm) {
if (perm.getName().equals("shutdownHooks")) {
if (threadContextClassLoaderIsPluginClassLoader()) {
throw new SecurityException("Installing shutdown hooks is not allowed.");
}
}
}
虽然addShutdownHook 在doPrivileged-block 中被调用,但我的SecurityManager 被调用。我错过了什么吗?我应该自己检查特权上下文吗?
【问题讨论】:
-
我找到了这篇文章 *.com/questions/2233761/...,它解决了确切的问题。如果我做对了,如果在 AccessController.doPrivileged() 块中完成 addShutdownHook 方法应该会成功,因为类
java.awt.Font具有 AppClassloader 的所有权限。尽管在 doPrivilieged() 块中调用,我仍然发现我的 SecurityManager 被要求获得权限。我应该如何在java.lang.SecurityManager.checkPermission(Permission)中检查这个? -
如果你在
doPrivileged中调用它,SecurityManager仍然需要检查“特权”类是否有权注册关闭挂钩。
标签: java securitymanager