3

我不精通 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);
                }
            });
4

1 回答 1

2

你很困惑。

似乎 SecurityManager 没有复制默认行为,并且在阅读后似乎它应用了 ${JAVA_HOME}/jre/lib/security/java.policy 下的默认策略,这是非常严格的。

a 的默认行为SecurityManager是遵守 Javadoc 中规定的约定,除非默认.policy文件允许,这确实是非常严格的。在没有安全管理器的情况下,默认行为是允许任何事情。

当没有安全管理器时,Java 的真正默认行为是什么?是“允许一切”吗

是的。

还是发生了其他事情?

不。

如果我想复制默认行为,除了上面的单个调整之外,我应该安装什么作为安全管理器?

正是这样做的安全管理器。如果你希望它除了你已经实现的一个覆盖之外什么都不强制,你必须为它的所有其他方法提供空覆盖。

于 2017-08-30T10:45:50.250 回答