除了对System.exit进行单个检查调整之外,与NO安全管理器相同的java SecurityManager

时间:2017-08-30 10:28:36

标签: java securitymanager java-security-manager

我不熟悉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);
                }
            });

1 个答案:

答案 0 :(得分:2)

你很困惑。

  

看起来SecurityManager不会复制默认行为,在阅读之后,它似乎会应用$ {JAVA_HOME} /jre/lib/security/java.policy下的默认策略,这是非常严格的。

SecurityManager的默认行为是遵守Javadoc中声明的合同,之外的默认.policy文件允许的合同,这确实是非常严格的。安全管理器的缺席中的默认行为是允许任何内容。

  

没有安全管理器时,Java的真正默认行为是什么?它是否允许一切'

  

或者还有其他事情发生了吗?

没有

  

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

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