Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/367.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么java安全管理器没有';t禁止创建新线程()或启动它?_Java_Multithreading_Securitymanager - Fatal编程技术网

为什么java安全管理器没有';t禁止创建新线程()或启动它?

为什么java安全管理器没有';t禁止创建新线程()或启动它?,java,multithreading,securitymanager,Java,Multithreading,Securitymanager,您知道为什么java安全管理器不禁止创建或启动新线程吗?新FileWriter位于安全管理器下,但new Thread()和threadInstance.start()都不是under安全管理器,并且可以调用 禁止它不是有用吗 实施起来难吗 或者创建和启动新线程与禁止它无关 线程构造函数中执行了访问检查,以查看调用方是否有权更改将添加新线程的线程组。这就是如何实现一个安全策略来禁止创建新线程 (还有一个关于创建线程组的检查……检查您是否有权将新组添加到其父组。) 因此,要回答您的问题: 为什么j

您知道为什么java安全管理器不禁止创建或启动新线程吗?新FileWriter位于安全管理器下,但new Thread()和threadInstance.start()都不是under安全管理器,并且可以调用

  • 禁止它不是有用吗
  • 实施起来难吗
  • 或者创建和启动新线程与禁止它无关

  • 线程构造函数中执行了访问检查,以查看调用方是否有权更改将添加新线程的线程组。这就是如何实现一个安全策略来禁止创建新线程

    (还有一个关于创建线程组的检查……检查您是否有权将新组添加到其父组。)

    因此,要回答您的问题:

    为什么java安全管理器既不禁止创建新线程()也不禁止启动它


    原因是JVM的当前安全策略允许父线程修改其
    ThreadGroup
    。您应该能够修改该策略设置以防止出现这种情况,从而防止创建子线程

    禁止它不是很有用吗

    是的。允许不受信任的代码创建/启动线程是不明智的,因为:1)一旦启动线程就不能安全地终止,2)创建/启动大量线程会使JVM(可能还有操作系统)崩溃

    实施起来难吗


    从您的角度来看,只需更改策略。

    接受的答案是不正确的:不可能定义一个安全策略来阻止代码使用标准Java SecurityManager创建和启动新线程

    假设您有以下代码:

    public class Test {
      public static void main(String [] args) {
        System.out.println(System.getSecurityManager() != null ? "Secure" : "");
        Thread thread = new Thread(
          new Runnable() { 
            public void run() {
              System.out.println("Ran");
            }
        });
        thread.start();
      }
    }
    
    然后使用以下命令运行它:

    java -Djava.security.manager -Djava.security.policy==/dev/null Test
    
    它将正常运行并输出:

    Secure
    Ran
    
    即使我们将安全策略设置为/dev/null,这将为任何代码授予零权限。因此,不可能授予更少的权限来阻止代码创建该线程

    这是因为标准java.lang.SecurityManager仅在代码尝试在根线程组中创建线程时执行权限检查。同时,SecurityManager的getThreadGroup方法始终返回当前线程的线程组,该线程组永远不会是根线程组,因此始终授予创建新线程的权限

    解决这个问题的一种方法是将java.lang.SecurityManager子类化,并重写getThreadGroup方法以返回根ThreadGroup。这将允许您根据代码是否具有java.lang.RuntimePermission“modifyThreadGroup”来控制代码是否可以创建线程

    因此,如果我们现在定义SecurityManager的子类,如下所示:

    public class ThreadSecurityManager extends SecurityManager { 
    
      private static ThreadGroup rootGroup;
    
      @Override
      public ThreadGroup getThreadGroup() {
        if (rootGroup == null) {
          rootGroup = getRootGroup();
        }
        return rootGroup;
      }
    
      private static ThreadGroup getRootGroup() {
        ThreadGroup root =  Thread.currentThread().getThreadGroup();
        while (root.getParent() != null) {
         root = root.getParent();
        }
        return root;
      }
    }
    
    然后再次运行命令,但这次指定子类ThreadSecurityManager:

    java -Djava.security.manager=ThreadSecurityManager -Djava.security.policy==/dev/null Test
    
    当我们尝试创建新线程时,测试类中出现异常:

    Exception in thread "main" java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "modifyThreadGroup")
    

    哪种编程语言?java,我添加到主题和描述中。有很多方法可以让JVM屈服。您将需要为至少一些线程提供不受信任的代码访问权限。能够创建线程是非常有用的。@Tom您通常不需要授予对线程的访问权限,但在这种情况下,您通常必须授予对替换工具的访问权限。如果Java的异步IO处理能力仍然不是很强的话,情况就不会那么糟糕了。在安全管理器下创建新线程时,我会在什么情况下收到异常?我在我自己的主java中尝试过-Djava.security.manager-Djava.security.policy=app.policy-cp bin pl.com.app,其中app.policy为空,在我的servlet中的Tomcat下尝试过(-security enabled)(在catalina.policy中没有线程权限),但我始终可以毫无例外地创建和启动新线程。“原因是JVM当前的安全策略允许父线程修改其线程组”--记录在哪里?大多数情况下,默认的policymanager态度是禁止未明确允许的一切安全检查记录在此处: