【问题标题】:Java SecurityManager @Override public void checkPermission(Permission perm)Java SecurityManager @Override public void checkPermission(Permission perm)
【发布时间】:2013-09-07 00:32:28
【问题描述】:

我正在构建一个 SWING 应用程序,还需要编写一个自定义 SecurityManager。如果我写一个像这样扩展 SecurityManager 的空类

public class Sandbox extends SecurityManager {}

它工作正常,这意味着 GUI 被正确呈现,并且所有特权(如 I/O)都被撤销。 但是我需要自定义 checkPermission 方法,每当我覆盖它时,它就不再起作用了...... 为什么连这样的事情都不行??

public class Sandbox extends SecurityManager {
  @Overide
  public void checkPermission(Permission perm) {
    super.checkPermission(perm);
  }
}

更新:显示问题的一个非常基本的示例是这样的

public static void main(String[] args) {

    System.setSecurityManager(new SecurityManager() {
        @Override
        public void checkPermission(Permission p) {
            if (some_condition_here) {
              // Do something here
            } else {
              // Resort to default implementation
              super.checkPermission(p);
            }
        }
    });

    new JFrame().setVisible(true);

}

删除“checkPermission”方法后应用程序可以正常工作,但我真的无法理解这一点。

【问题讨论】:

标签: java swing securitymanager


【解决方案1】:

根据堆栈上的所有代码授予权限。所有调用者都必须具有所需的权限。如果您重写该方法并调用超类方法,您的代码也在堆栈上,这意味着您的代码库(您的自定义 SecurityManager 所属的位置)必须具有您(您的调用者)要求的权限。

这就是覆盖与否的区别。如果您不覆盖该方法,则只有(可能有特权的)调用者的代码在堆栈上,它将获得请求的权限。如果您覆盖该方法,您的代码也在堆栈上,并且也必须具有权限。

因此,如果您想实现一个自定义 SecurityManager 来调用继承的检查方法,您必须配置继承的(基于策略的)逻辑来为您的 SecurityManager 提供它应该能够授予的所有权限。建议将 SecurityManager 与应用程序的其余部分分离到不同的代码库中,这样只有 SecurityManager 而没有其他任何东西可以获得慷慨的权限。

【讨论】:

  • 所以他基本上需要涵盖所有可能向安全经理提出的请求。但是你的回答听起来更专业! +1
  • 不过,从 Oracle 文档中,他们建议从 public void checkRead(String file) 调用(例如) super.checkRead()。而且我不断得到同样的异常被抛出
  • 正如 Holger 所说,堆栈上的所有内容都经过权限检查。所以你也需要在子类中实现它们。
  • 您覆盖哪种检查...方法并不重要。无论如何,所有这些方法都委托给checkPermission(Permission)。他们在那里只是出于历史原因。您可以使用单个 checkPermission 方法控制整个安全性。但是,如果您覆盖这些方法中的任何一个并调用其超级实现,您的代码就在堆栈上,并且您的自定义安全管理器的代码库也必须具有此权限才能成功进行此检查。
  • 回想一下:如果您还没有为默认安全管理器配置策略,则默认设置是(几乎)不授予对 JVM 之外的任何代码的任何权限。如果您的代码是主应用程序和对属于您自己的代码库的资源的文件访问权限,您可能获得的唯一权限是“exitVM”。
【解决方案2】:

如果您调用超类'checkPermission(p),您不必首先重写该类。把它注释掉,然后它就可以工作了。

超类调用java.security.AccessController.checkPermission(perm),当java.lang.SecurityManager 未调用时,这似乎抛出了java.security.AccessControlException

就我而言,它说:

Could not load Logmanager "null"
java.security.AccessControlException: access denied (java.util.PropertyPermission java.util.logging.manager read)

等等

public class SecurityManagerExample
{
  public static void main(String[] args)
  {
    System.setSecurityManager(new SecurityManager()
    {
      @Override
      public void checkPermission(Permission p)
      {
        //super.checkPermission(p);
      }
    });

    new JFrame().setVisible(true);
  }
}

我找到了关于如何编写安全管理器的tutorial。我还建议您阅读 java doc 和 oracle 提供的示例。


更新

查看method summary 并覆盖您要禁止的功能。 我发现您需要明确允许您想要拥有的功能。

这里是一个例子:

public class SecurityManagerExample
{

  public static void main(String[] args)
  {
    System.setSecurityManager(new SecurityManager()
    {
      @Override
      public void checkWrite(String file) {
        // no exception is thrown, i. e. creating files is allowed in general
      }

      @Override
      public void checkDelete(String file)
      {
        if (file.equals("test.xml"))
        {
          throw new SecurityException("Not allowed to delete test.xml!");
        }
      }
    });

    File f = new File("test.xml");
    try
    {
      f.createNewFile();
    }
    catch (IOException e)
    {
    }

    f.delete();

  }
}

输出

Exception in thread "main" java.lang.SecurityException: Not allowed to delete test.xml!
    at main.SecurityManagerExample$1.checkDelete(SecurityManagerExample.java:60)
    at java.io.File.delete(File.java:902)
    at main.SecurityManagerExample.main(SecurityManagerExample.java:74)

【讨论】:

  • 谢谢迈克,我已经完成了那个教程,但不幸的是它没有帮助:(无论如何我已经更新了我的代码 sn-p 以明确我不需要打电话super.checkPermission(p); 在该方法中,但我的示例只是一个简化。顺便说一句,“注释掉”与在根本没有 SecurityManager 的情况下运行程序的效果相同
  • 然后检查我在您的问题下发布的另一个链接。加上java doc,还有另一个关于oracle的教程docs.oracle.com/javase/tutorial/essential/environment/…
  • 既然你更新了你的评论:我的意思是,如果你想使用基类的功能,不要扩展它。如果您想扩展它,请编写您自己的关于允许或不允许的策略。如果您只是想禁止特殊情况。您需要覆盖另一种方法。由于所有方法最终都会调用checkPermission,因此并不容易对其进行适当的覆盖。
猜你喜欢
  • 2018-07-28
  • 1970-01-01
  • 2012-12-07
  • 1970-01-01
  • 1970-01-01
  • 2022-12-19
  • 1970-01-01
  • 2011-01-24
  • 2014-04-05
相关资源
最近更新 更多