6

我正在构建一个 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”方法,但我真的无法理解这一点。

4

2 回答 2

1

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

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

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

于 2013-09-04T12:47:09.690 回答
0

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

超类的调用,当不被调用时java.security.AccessController.checkPermission(perm),它似乎抛出了java.security.AccessControlExceptionjava.lang.SecurityManager

就我而言,它说:

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);
  }
}

我找到了有关如何编写安全管理器的教程。我还建议您阅读 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)
于 2013-09-04T11:42:29.980 回答