我想强制执行一些第三方库类的安全管理器,所以我要做类似的事情:

  SecurityManager original = System.getSecurityManager();
  System.setSecurityManager(for3rdOne);
  try {
      thirdparty.doStuff();
  } finally {
      System.setSecurityManager(original);
  }


到目前为止,效果很好,代码可以完美地将第三方限制在某些约束下。但是我有几个疑问,我找不到答案:


如果我在多个线程中执行此代码,那么如果setSecurityManager具有全局作用域,那么返回原始安全管理器将对第三方开放违约怎么办?
如果setSecurityManager仅具有当前线程的作用域,如果我的线程在调用第三方之后结束,我是否需要担心返回原始的安全管理器?
第二个疑问有一定的技巧,例如新的安全管理器for3rdOne不允许调用setSecurityManager,因此在退出沙盒代码后,我需要做一些动作以允许它。

最佳答案

setSecurityManager具有全局作用域,因此最简单的解决方案是一劳永逸。但是,如果应在不同的安全策略下执行代码的某些部分,则该代码应与第三方代码同步。一种解决方案是使用输入队列启动一个特殊线程,该线程执行所有对安全策略敏感的代码。线程可以视为单线程执行程序,但对于特殊的任务类:每个任务都有一个属性setSecurityManager(for3rdOne),该属性在执行任务之前已被检查并用于调用securityManager

如果对安全性敏感的代码过多,并且单线程成为瓶颈,则可以详细说明更复杂的解决方案,但是我相信没有通用的解决方案,需要更多信息才能提供建议。大多数并行解决方案是为每种类型的安全管理器使用单独的JVM,但这可能是不合适的,因为进程之间有大量的数据浮动。

更新资料

区分不同调用者安全策略的最简单方法是为不同的线程分配不同的权限-因为很容易确定当前线程,然后确定其类型(类或接口)。另一种方法是使用SecurityManager.getSecurityContext()读取当前上下文,对其进行扫描并检查是否存在功能受限的类。

09-05 17:14