我正在尝试找到一个没有被广泛讨论的简单问题的最佳解决方案。
我的应用程序有很多可以创建和编辑数据的用户。用户应该只查看和编辑他的数据,而不是其他人的数据。
想想爱丽丝,她有一家餐厅 A,有一个菜单 MenuA,而鲍勃有一家餐厅 B,有一个菜单 MenuB。
我有用于 CRUD 餐厅和菜单的 API,并且我可以轻松地仅向具有正确声明和角色的登录用户授权。我现在想做的是阻止鲍勃访问爱丽丝的餐厅或菜单,反之亦然。
例如,鲍勃应该被授权PUT /api/restaurants/B
但应未经授权PUT /api/restaurants/A
甚至PUT /api/restaurants/A/menus/x
这里提供了一种可能的解决方案ASP.NET MVC 属性仅允许用户编辑他/她自己的内容 https://stackoverflow.com/questions/11037213/asp-net-mvc-attribute-to-only-let-user-edit-his-her-own-content。此解决方案需要创建自定义授权属性来主动检查登录用户是否是所访问实体的专有。这些实体有一个 userId 字段来检查发出请求的用户是否是数据的所有者。
这个解决方案很好很干净,但缺乏一些功能。
模型中的每个实体都应该有一个 userId 字段,并且只能由所有者访问,或者对于每个实体,我需要导航到授权模型的根实体(例如,访问菜单,我需要查询父实体 Restaurant 来检查如果 MenuB 位于用户拥有的餐厅内)。
要实现多个所有者(例如餐厅经理),逻辑将复杂得多。我还担心这里的开销,因为基本上每个调用都需要执行一些查询来检查数据访问,但这可能不是问题。
有最佳实践吗?
您想要做的是实施基于属性的访问控制或abac /questions/tagged/abac.
在 ABAC 架构中,您有策略执行点 (PEP) 的概念,它拦截 API 调用并确定调用是否应该通过。 PEP 将 API 调用转换为授权请求,并将其发送到中央策略决策点 (PDP)。
以下架构总结了流程。
PDP 配置有一组策略,用于确定允许什么和拒绝什么。例如,您可以编写如下策略:
- 餐厅老板可以查看餐厅页面
- 餐厅老板可以编辑该餐厅的菜单。
- 顾客可以查看任何公开餐厅的菜单。
您可以使用两种语言编写策略:xacml /questions/tagged/xacml or alfa /questions/tagged/alfa.
例如,在 ALFA 中,策略如下所示:
namespace restaurant{
attribute userId{
category = subjectCat
id = "restaurant.userId"
type = string
}
attribute owner{
category = resourceCat
id = "restaurant.resourceCat"
type = string
}
policy restaurant{
target clause objectType == "restaurant"
apply firstApplicable
rule ownerCanView{
target clause actionId == "view"
permit
condition userId == restaurant.owner
}
}
}
您所需要的只是使用 XACML 3.0 策略决策点。有 Java 和 .NET 实现以及商业实现。看看这个关于 .Net 授权的博客文章 https://www.axiomatics.com/blog/entry/custom-claims-based-authorization-in-net-using-axiomatics-pep-sdk-for-net.html.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)