我不熟悉java安全管理器,因此想确认我的理解:
我有一个java进程随机停止(关闭钩子运行),即使没有人杀死它的痕迹。因此,我决定安装一个安全管理器并覆盖checkExit(int status)
,以确保停止的原因不是调用System.exit()
。基本上我写了这个:
System.setSecurityManager(new SecurityManager() {
@Override
public void checkExit(int status) {
Thread.dumpStack();
super.checkExit(status);
}
});
我原以为我的程序会像往常一样运行,唯一的变化就是如果调用System.exit()就会转储堆栈跟踪。我发现事实并非如此。它无法从此安全例外开始:
java.security.AccessControlException: access denied ("java.util.PropertyPermission" "config" "read")
at java.security.AccessControlContext.checkPermission(AccessControlContext.java:472) ~[na:1.8.0_74]
at java.security.AccessController.checkPermission(AccessController.java:884) ~[na:1.8.0_74]
at java.lang.SecurityManager.checkPermission(SecurityManager.java:549) ~[na:1.8.0_74]
at java.lang.SecurityManager.checkPropertyAccess(SecurityManager.java:1294) ~[na:1.8.0_74]
at java.lang.System.getProperty(System.java:717) ~[na:1.8.0_74]
at Main.main(Main.java:161) ~[na:na]
看起来SecurityManager不会复制默认行为,在阅读之后,它似乎会应用${JAVA_HOME}/jre/lib/security/java.policy
下的默认策略,这是非常严格的。
没有安全管理器时,Java的真正默认行为是什么?它是否允许一切'或者还有其他事情发生了吗?
除了上面的单一调整之外,如果我想复制默认行为,我应该作为安全管理器安装什么?
在最后一点,我可以看到System.setSecurityManager()
实际上需要java.lang.SecurityManager
的实例,这意味着我被迫使用该实现(依赖于策略文件)。覆盖该类中的方法以复制NO安全管理器的实际默认行为的最有效方法是什么?
编辑:根据下面的讨论,这似乎是这样做的
System.setSecurityManager(new SecurityManager() {
@Override
public void checkPermission(Permission perm) {
return; // no security manager behaviour
}
@Override
public void checkPermission(Permission perm, Object context) {
return; // no security manager behaviour
}
@Override
public void checkExit(int status) {
Thread.dumpStack();
super.checkExit(status);
}
});
答案 0 :(得分:2)
你很困惑。
看起来SecurityManager不会复制默认行为,在阅读之后,它似乎会应用$ {JAVA_HOME} /jre/lib/security/java.policy下的默认策略,这是非常严格的。
SecurityManager
的默认行为是遵守Javadoc中声明的合同,除之外的默认.policy
文件允许的合同,这确实是非常严格的。安全管理器的缺席中的默认行为是允许任何内容。
没有安全管理器时,Java的真正默认行为是什么?它是否允许一切'
是
或者还有其他事情发生了吗?
没有
除了上面的单一调整之外,如果我想复制默认行为,我应该作为安全管理器安装什么?
正是这样做的安全经理。如果你希望它除了你实现的一个覆盖之外什么都不强制执行,你必须为其所有其他方法提供空覆盖。