Java SecurityManager@Override public void checkPermission(权限perm)

Java SecurityManager@Override public void checkPermission(权限perm),java,swing,securitymanager,Java,Swing,Securitymanager,我正在构建一个SWING应用程序,还需要编写一个定制的SecurityManager。如果我写一个空类,它像这样扩展SecurityManager public class Sandbox extends SecurityManager {} 它工作正常,这意味着GUI被正确呈现,所有特权(如I/O)都被撤销。 但是,我需要自定义checkPermission方法,每当我重写它时,它就不再有效。。。 为什么这样的事情都不管用 public class Sandbox extends Secur

我正在构建一个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”方法应用程序工作正常,但我真的无法解决这个问题。

如果调用超类“
checkPermission(p)
,则不必首先重写该类。把它注释掉,它就会工作

superclas调用
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)
等等

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


更新

查看并覆盖您想要禁止的功能。 正如我发现的那样,您还需要明确地允许您想要的功能

这里有一个例子:

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)

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

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


因此,如果要实现调用继承检查方法的自定义SecurityManager,则必须配置继承的(基于策略的)逻辑,以便为SecurityManager授予它应该能够授予的所有权限。建议将SecurityManager与应用程序的其他部分分离成不同的代码库,以便只有SecurityManager和其他任何部分都可以获得慷慨的权限。

为了更快地获得帮助,请发布一个。我已经用一个示例更新了这个问题这可能也很有趣好-我很困惑,抱歉..谢谢mike,我已经阅读了该教程,但不幸的是它没有帮助:(无论如何,我已经更新了我的代码片段,以明确我不需要简单地调用super.checkPermission(p);在该方法中,但我的示例只是一个简化。顺便说一句,“注释它”与在没有SecurityManager的情况下运行程序的效果相同,然后检查我在您的问题下发布的另一个链接。加上java文档,还有一个关于oracle的教程,因为您更新了您的评论:我的意思是,如果您想使用基类的功能,不要扩展它。如果您想扩展它,不要扩展它如果你只想禁止一个特殊情况,你需要重写另一个方法。因为所有方法最后都调用了
checkPermission
,所以重写它appropiate并不容易。所以他基本上需要覆盖所有可能向安全经理提出的请求。但是你的回答听起来更专业fessional!+1Still,从Oracle文档中,他们建议从public void checkRead(字符串文件)调用(例如)super.checkRead()。我一直得到相同的异常。正如Holger所说,堆栈上的所有内容都会检查权限。因此,您也需要在子类中实现它们。覆盖哪个check…方法无关紧要。所有这些方法都委托给
checkPermission(permission)
无论如何。它们只是出于历史原因存在的。您可以使用单一的checkPermission方法控制整个安全性。但是,如果您重写这些方法中的任何一个并调用其超级实现,则您的代码位于堆栈上,并且自定义安全管理器的代码库也必须具有此检查成功的权限d、 回想一下:如果您没有为默认安全管理器配置策略,那么默认设置是(几乎)不向JVM之外的任何代码授予任何权限。如果您的代码是对属于您自己的代码库的资源的主应用程序和文件访问权限,那么您可能获得的唯一权限就是“exitVM”。
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)