【问题标题】:Enable the Java SecurityManager with AllPermission使用 AllPermission 启用 Java SecurityManager
【发布时间】:2019-04-08 03:28:05
【问题描述】:

我试图让自己熟悉SecurityManager,但即使是这个简单的场景也失败了。当我从 IDE 内部或命令行运行以下命令时,我得到以下 exception;

access denied ("java.util.PropertyPermission" "java.home" "read")

我以为我允许使用此代码进行所有操作:

Policy.setPolicy(new Policy() {

    @Override
    public PermissionCollection getPermissions(CodeSource codesource) {
        Permissions perm = new Permissions();
        perm.add(new AllPermission());
        return perm;
    }
});
System.setSecurityManager(new SecurityManager());
System.out.println(System.getProperty("java.home"));

这与来自 JVM 的派生策略有关吗?我怎样才能干净地setPolicy()

下面的代码似乎也发生了同样的误解:

System.setSecurityManager(new SecurityManager());
final Permissions allPermission = new Permissions();
allPermission.add(new AllPermission());
AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
    System.out.println(System.getProperty("java.home"));
    return null;
}, new AccessControlContext(new ProtectionDomain[]{new ProtectionDomain(null, allPermission)}));

更新:第二种情况是可以理解的,因为提供的权限只是进一步的限制:(javadoc)该操作是通过调用者的保护域拥有的权限的交集来执行的,以及指定AccessControlContext所代表的域所拥有的人

【问题讨论】:

  • 我正在尝试提高我的 java 应用程序的安全性,为此我需要了解这些机制。仅启用 SecurityManager 是不可能的,因为我需要一些例外。我必须更多地了解这一切是如何协同工作的,因为它不是标准用例。
  • 我无法重现这个(在 JDK 8 和 11 上试过)。我怀疑默认策略实施是原因。在安全管理器和您的自定义策略之间插入了一些非标准的东西,有效地防止或覆盖了对后者的查询;例如为您的类分配了static 非特权保护域的自定义类加载器。
  • @Uux 非常感谢您抽出宝贵的时间。那么在您的情况下,您可以访问 java.home 属性吗?如果是,您能否提供您的政策文件?
  • @Karussell 是的,你的 sn-p 运行得很好(在一个普通的旧 main 方法中,通过普通的旧 java -cp &lt;classpath&gt; &lt;main-class&gt; 启动)。我没有修改我的 .policy 文件,因为它最终无关紧要——一旦Policy.setPolicy 返回,它是 your 被咨询的策略实施,而不是以前的默认文件-支持一个。您可能想尝试使用-Djava.security.debug="access,failure" 运行并将其输出附加到您的问题中。
  • 我现在更好地理解了我想要实现的目标:我想要一种编程方式来设置策略,如果我没有设置权限,那么 System.getProperty 调用会失败,如果我授予 PropertyPermission 或AllPermission 然后调用通过。事实上,第二部分现在可以工作(不知道为什么),但第一部分未经任何许可就通过了。而当我执行 Policy.getPolicy 时,情况正好相反(两个部分都失败了)

标签: java java-security securitymanager


【解决方案1】:

您在上面的哪个上下文中运行您的代码?

从带有简单 JVM 的命令行或在某个 JavaEE 容器之上运行的 web 应用程序中?在哪个操作系统上?使用哪个 JVM(Oracle、OpenJDK、IBM J9...)以及哪个版本?

如果您从命令行运行,请查看位于 JVM 安装路径中的 java.policy 文件。它的内容可能会缩小你的授权范围,从而阻止你访问这个特定的系统变量?

【讨论】:

  • 更新了我的问题。那么策略文件会覆盖Policy.setPolicy 吗?如果真的是这种情况,那么这种方法的 javadocs 不仅会误导 IMO。
【解决方案2】:

我能够在 Policy.setPolicy() 调用之前使用额外的 Policy.getPolicy() 重新创建您的案例,它影响行为的原因是,通过 get policy 调用,您触发了默认策略创建,以及来自 @987654324 的权限@ 已设置,但没有 setSecurityManager(),它们不会被激活,这就是当您执行自定义 AllPermission 策略集时,您仍然会遇到 "java.util.PropertyPermission" "java.home" "read" 问题,因为许多此类默认策略没有被覆盖制定政策。确实非常混乱的结构。

Policy.getPolicy();
Policy.setPolicy(policyWithAllPermission);
System.setSecurityManager(new SecurityManager());
System.out.println(System.getProperty("java.home"));
// results in 'access denied ("java.util.PropertyPermission" "java.home" "read")'

但如果您使用以下自定义策略;

Policy allPermissionPolicy = new Policy() {

    @Override
    public boolean implies(ProtectionDomain domain, Permission permission) {
        return true;
    }
};

它会覆盖所有权限定义,并允许所有操作通过,这可能会解决这种混乱。

【讨论】:

  • 事实证明,您从一开始就直觉地走在正确的轨道上(额外的功劳是因为在 cmets 中除了 setPolicy 之外和之前还提到了调用 getPolicy 的 OP 参考)!至于故事的“为什么,究竟”部分,请参见java.security.Policy#initPolicy的来源。
猜你喜欢
  • 1970-01-01
  • 2014-04-05
  • 1970-01-01
  • 1970-01-01
  • 2010-11-19
  • 1970-01-01
  • 2017-11-16
  • 1970-01-01
  • 2014-04-26
相关资源
最近更新 更多