3

我们的产品建立在客户端-服务器架构上,服务器用 Java 实现(我们使用 POJO 和 Spring 框架)。我们在服务器上有两个 API 级别:

  • 外部 API,它使用 REST Web 服务 - 对于外部客户端和与其他服​​务器的集成很有用。
  • 内部 API ,它使用纯 Java 类 -对于内部的实际代码(业务逻辑多次调用 API 调用)以及与公司内部开发并作为我们产品的一部分部署的 plusins 集成很有用。外部 REST API 也使用内部 API。

我们在内部 API 中实现了权限检查(使用 Spring 安全性),因为我们希望在最低 API 级别控制访问。

但是问题来了:在 API 级别上定义了一些操作,这些操作被认为对当前登录的用户是禁止的,但应该由服务器本身顺利执行。例如,可以禁止用户删除某些实体,但服务器可能希望删除该实体,作为用户执行的某些其他操作的副作用,我们希望允许这样做。

那么,允许服务器执行实际登录用户可能禁止的操作(在某种超级用户模式下)的最佳方法是什么?

正如我所看到的,我们有几个选择,每个都有其优点和缺点:

  1. 在外部级别 API (REST) 中实施权限检查 - 不好,因为插件将绕过权限检查。
  2. 在请求被授予后关闭当前线程的权限检查 - 太危险了,我们可能允许太多应该被禁止的服务器操作。
  3. 明确要求内部 API 级别以特权模式执行操作(就像 java 安全框架中的 PrivilegedAction 一样) - 太冗长了。

由于上述方法都不是理想的,我想知道这个问题的最佳实践方法是什么?

谢谢。

4

3 回答 3

2

安全性应用于模块的边界。如果我理解您,您的系统将安全性应用于(大致)相同 API 的两个抽象级别。这听起来很复杂,因为您必须对整个两个 API 进行双重安全检查。

考虑将 REST 所需的方法从内部 API 迁移到外部 API,并删除内部 API 中的安全内容。

  • 外部 API 将管理外部客户端的安全性(在您的应用程序的边界)
  • 内部 API 将严格保留给内部应用程序和插件使用(你会很乐意破解它,因为没有外部客户端绑定到它)

您真的需要控制插件对您的应用程序逻辑的权限吗?有充分的理由吗?毕竟,插件是由贵公司开发的。也许向插件的开发人员解释不应该做什么的正式文档,或者插件的安全测试套件验证(例如,断言插件不调用“this”方法)也可以完成这项工作。

如果您仍然需要将这些插件视为“不受信任”,请将它们所需的方法添加到您的外部 API(在您的应用程序边界上)并为每次使用创建特定的安全配置文件:“restProfile”、“clientProfile”和“pluginProfile”。每个人都将对您的外部 API 方法拥有特定的权限。

于 2009-02-25T03:56:02.273 回答
1

听起来您需要两个级别的内部 API,一个暴露给插件,一个不暴露。

启用它的最佳方法是使用 OSGi(或 Spring 模块)。它允许您明确声明其他模块(即 REST 模块和插件模块)可以访问哪些包和类。这些将是您的新内部 API 的公开级别,您将使用 Spring Security 进一步有选择地限制访问。内部包和类将包含执行所有低级操作(如删除实体)的方法,您将无法直接调用它们。一些公开的 API 只会通过安全检查复制内部 API,但这没关系。

最好的方法的问题是 Spring Modules 在我看来仍然有点太不成熟,甚至无法放入一个新的 webapp 项目中。我绝不会想把它硬塞进一个旧项目中。

您可能可以使用 Spring Security 和 AspectJ 实现类似的目标,但令我震惊的是,性能开销会令人望而却步。

如果您可以重新构建系统,那么一种非常酷的解决方案是让需要安全提升的任务脱机,或者让它们异步。使用 Quartz 和/或 Apache Camel(或适当的 ESB),您可以使“删除我的帐户”方法创建一个离线任务,该任务可以在将来作为具有管理员权限的原子工作单元执行。这意味着您可以在与实际发生删除的完全独立的线程中对请求删除帐户的用户进行干净的安全检查。这将具有使网络线程更具响应性的优势,尽管您仍然希望立即执行某些操作以保持所请求的操作已完成的错觉。

于 2009-02-25T10:46:09.730 回答
0

If you're using Spring, you may as well utilize it fully. Spring offers AOP that allows you to use interceptors and perform these cross-system checks, and in the event of an unauthorized action, prevent the action.

You can read more about this in Spring's online documentation here.

Hope this helps...

Yuval =8-)

于 2009-02-24T14:41:45.147 回答