Policy.setPolicy() 似乎无法正常工作

Policy.setPolicy() doesn't seem to work properly

我想通过定义我自己的 class 来设置自定义 Policy 来扩展策略 class,如下所示:

public class MyPolicy extends Policy {

    public MyPolicy() {
        super();
    }

    @Override
    public PermissionCollection getPermissions(ProtectionDomain domain) {
        // return PermissionCollection with no permissions
        PermissionCollection pc = new PermissionCollection();
        return pm;
    }
}

然后,在我的应用程序开始时,我设置了我的自定义 Policy class 并且我还启用了 SecurityManager 以便新策略生效:

Policy.setPolicy(new MyPolicy());
System.setSecurityManager(new SecurityManager());

上面的问题是它不起作用。上述示例的想法是引入一个策略,该策略将阻止应用程序执行任何需要任何类型许可的操作。因此,例如,当我的应用程序执行时:

System.getenv();

我预计上述结果会导致 AccessControlException 应该由 SecurityManager 抛出。相反,我的应用程序运行得很好。但是,当我按如下方式初始化策略和 SecurityManager 时:

// setting the policy twice intentionally 
Policy.setPolicy(new MyPolicy());
Policy.setPolicy(new MyPolicy());
System.setSecurityManager(new SecurityManager());

然后执行 System.getenv() 实际上会产生预期的 AccessControlException

这是我的questions/concerns,我想得到解释:

当部分实现本身可能不受信任时,处理基于堆栈检查的安全机制存在 "interesting" 问题。使用 bootstrap classes 实现时会容易得多,因为 null class 加载器绕过检查。

当您第一次setPolicy时,Policy 实现的ProtectionDomain 被授予所有权限。所以您的所有代码都享有特权 - 而不是您想要的。

对于随后的 setPolicy 调用,先前的 Policy 提供 Policy 实现 ProtectionDomain 的权限。在您的情况下,这会导致您的所有代码都具有空的 PermissionCollection 权限。 (你可能应该调用 setReadOnly 这个 - 讨厌 API。而且它是一个抽象 class,所以不应该编译。)

因此,您可能希望使用单独的 class 加载程序来加载不受信任的代码和安全机制。

只有您可能会假设没有任何权限而破坏了很多东西。 Boot classes 因为它们的 null class 加载程序而获得通过。例如,加载 classes 可能需要权限,因此您不想拒绝那里的所有内容。

最好使用正常的策略文件配置来配置策略。