4

这个问题与这个问题非常相似,但我需要专注于不同的问题。

假设我有一个带有大型数据库(即电影数据库)的应用程序。应用程序的用户应该能够添加她自己的插件并能够运行它们。

场景可能如下所示:

  • 启动主应用程序
  • 将 stats-plugin.jar 放在 /app/plugins 目录中
  • 告诉主应用加载新插件
  • 告诉应用列出插件
  • 选择一个插件(例如刚刚安装的)并运行它
  • stats-plugin.jar 查询有关电影的数据库并计算恐怖电影的数量,返回计数
  • 主应用程序呈现结果


每个插件都可以有几个标准方法(一个通用Plugin接口)可以调用,例如onInitializeonRun等等。

主应用程序需要保证的是,如果插件崩溃(例如除以 0),主应用程序将保持稳定(例如,将显示错误对话框,但不会自行崩溃)。还应该可以限制执行时间并检查插件正在执行的操作。

这一切都归结为一个沙盒插件环境。最重要的事情是:插件风格的可扩展性和沙盒插件——只允许安全操作(例如读取数据库,但不更新它)。

该插件不必用 Java 编写。它需要以某种方式执行……它甚至可以是一个 JavaScript 文件……如果可能的话。

您将如何处理这样的任务?

4

4 回答 4

1

您应该考虑使用安全管理器,并可能定义一些您自己的权限。在定义策略时,已经有一组常用的权限可供您使用。

请注意,对 RDBMS 的只读访问不太可能在您的 Java 环境范围内。相反,这通常使用具有特定权限的单独 RDBMS 用户来处理。您的框架需要使用该用户名连接到数据库。

于 2012-06-20T17:42:11.600 回答
1

可以使用您自己的安全策略文件和您自己的安全管理器来执行类似的操作。基本上,授予您自己的 jar AllPermission 和插件 jar 较少的权限。但是,这样一来,您将无法限制不受信任的小程序可用的操作,因此仍然可以编写一个创建无限循环或分配 100GB RAM 的线程。

为了允许数据库访问但只允许特定操作,您必须提供自己的 API(位于您的受信任的罐子之一中),该 API 将仅提供受信任的操作(例如首先验证 SELECT 语句)并在之后调用 AccessController.doPrivileged 如果它是信任执行操作。由于不受信任的代码可能无法打开套接字连接(除非允许特定主机),因此代码将无法以这种方式与数据库混淆。

但是,正确实现安全管理器可能会很棘手(在实现中经常会发现错误,例如最近在 Batik Squiggle 中),因此使用模拟语言(例如 JavaScript/Rhino)可能更安全。

于 2012-06-20T17:43:49.957 回答
0

您也许可以使用Java Authentication and Authorization Service来实现这样的可插入架构。使用 JAAS,您可以执行具有受限访问控制权限的插件。ACL 可以限制打开套接字连接、写入文件、打开数据库连接等,

对于数据库访问,您可以通过 JNDI 数据源提供与插件的数据库连接,并使用只能读取而不能更新数据库的 DB 用户配置数据源。

于 2012-06-20T17:54:57.313 回答
-2

我不认为 java 是运行不受信任插件的合适平台。一旦插件运行,它将能够执行主机程序可以执行的所有操作。

您需要创建自己的抽象层和“安全”操作沙箱,作为主程序的一部分执行。该插件可以提供您解释为程序的数据。你不能让插件运行。

于 2012-06-20T17:31:46.163 回答