检查服务器端API的权限

时间:2009-02-24 13:01:14

标签: java security spring permissions spring-security

我们的产品构建在客户端 - 服务器架构之上,服务器用Java实现(我们在Spring框架中使用POJO)。我们在服务器上有两个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 个答案:

答案 0 :(得分:2)

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

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

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

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

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

答案 1 :(得分:1)

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

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

最好的方法是Spring Modules让我觉得有点太不成熟,甚至投入新的webapp项目。我不可能把它变成一个旧项目。

你可能可以使用Spring Security和AspectJ实现类似的功能,但是我觉得性能开销太高了。

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

答案 2 :(得分:0)

如果你使用的是Spring,你也可以充分利用它。 Spring提供AOP,允许您使用拦截器并执行这些跨系统检查,并在未经授权的情况下阻止此操作。

您可以在Spring的在线文档here中阅读更多相关信息。

希望这会有所帮助......

Yuval = 8 - )