2

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

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类,并且我还启用了,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

以下是我想要解释的问题/疑虑:

  • 为什么设置SecurityManager后必须设置两次Policy才能使Policy生效?
  • 上面的问题是某种错误还是 Policy 类故意设计成这种方式(如果是这样 - 为什么?)?
4

1 回答 1

1

当部分实现本身可能不受信任时,处理基于堆栈检查的安全机制会出现“有趣”的问题。当它使用引导类实现时要容易得多,因为null类加载器的检查被绕过了。

当您setPolicy第一次使用时,将ProtectionDomain授予Policy执行的所有权限。所以你所有的代码都是特权的——不是你想要的。

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

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

只有您可能通过假设没有任何权限而破坏了很多东西。引导类因其null类加载器而获得通过。例如,加载类可能需要权限,因此您不想拒绝那里的所有内容。

使用普通的策略文件配置来配置策略要好得多。

于 2015-07-16T17:23:43.380 回答