我们的产品建立在客户端-服务器架构之上,服务器是用 Java 实现的(我们使用 POJO 和 Spring 框架)。我们在服务器上有两个 API 级别:
- 外部 API,它使用 REST 网络服务 - 对于外部客户端以及与其他服务器的集成很有用。
- 内部 API,它使用纯 Java 类 - 对于内部的实际代码(业务逻辑调用 API 调用的次数)以及与公司内部开发和部署的 plusins 的集成非常有用我们产品的一部分。外部 REST API 也使用内部 API。
我们在内部 API 中实现了权限检查(使用 Spring 安全性),因为我们希望在最低 API 级别控制访问。
但问题来了:有一些定义在API层面的操作对于当前登录的用户来说被认为是禁止的,但这些操作应该由服务器本身顺利执行。例如,用户可能禁止删除某些实体,但服务器可能希望删除此实体作为用户执行的某些其他操作的副作用,我们希望允许这样做。
那么允许服务器执行可能被实际登录用户禁止的操作(在某种 super 用户模式下)的最佳方法是什么?
在我看来,我们有多种选择,每种选择各有利弊:
- 在外部级 API (REST) 中实现权限检查 - 不好,因为插件会绕过权限检查。
- 在授予请求后关闭当前线程的权限检查 - 太危险了,我们可能会允许太多本应禁止的服务器操作。
- 明确要求内部 API 级别以特权模式执行操作(就像 Java 安全框架中的 PrivilegedAction)- 过于冗长。
由于上述方法都不是理想的,我想知道解决这个问题的最佳实践方法是什么?
谢谢。
最佳答案
安全性应用于模块的边界。如果我理解你,你的系统在(大致)相同的 API 的两个抽象级别上应用安全性。这听起来很复杂,因为您必须对整个两个 API 进行双重安全检查。
考虑将 REST 所需的方法从内部 API 迁移到外部 API,并删除内部 API 中的安全内容。
- 外部 API 将管理外部客户端的安全性(在您的应用边界)
- 内部 API 将严格保留供内部应用程序和插件使用(您很乐意破解它,因为没有外部客户端受其约束)
您真的需要控制插件对您的应用程序逻辑的权限吗?有充分的理由吗?毕竟,插件是由您的公司开发的。也许向插件开发人员解释不应该做什么的正式文件,或者插件的安全测试套件验证(例如,断言插件不调用“this”方法)也可以完成这项工作。
如果您仍然需要将这些插件视为“不受信任”,请将它们所需的方法添加到您的外部 API(在您的应用程序边界上)并为每次使用创建特定的安全配置文件:“restProfile”、“clientProfile”和“pluginProfile” ”。每个人都对您的外部 API 方法拥有特定的权利。
关于java - 服务器端 API 中的权限检查,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/581655/