【问题标题】:Where to apply domain level permissioning在哪里应用域级别权限
【发布时间】:2015-06-13 14:38:33
【问题描述】:
我认为,许可/授权(不是身份验证)是一个跨领域的问题。
在洋葱架构或六边形架构中,应该在哪里执行权限?所需许可的示例如下:
- 过滤返回到前端(UI、API 或其他)的数据
- 验证是否可以执行业务操作
理想情况下,通过单一职责原则,执行业务操作和返回数据的代码根本不需要知道用户的权限。该功能的实现应该知道如何执行业务操作或查询存储库或域服务 - 就是这样。
实现与执行业务操作或返回数据的类相同的接口的包装器/外观是否是放置此权限的地方?还是有更好的办法?
此外,如果最佳做法是按活动而不是按角色进行许可,那么说许可应该由仅用于返回数据的服务执行是否仍然有效?
【问题讨论】:
标签:
design-patterns
permissions
authorization
onion-architecture
hexagonal-architecture
【解决方案1】:
有人可能会争辩说,访问检查应始终尽可能靠近执行操作的代码,以减少有人找到绕过访问检查的侧通道的机会。也就是说,如果您可以使用包装类来保证在生产系统中访问检查将始终到位,我认为这很好。
验证业务操作是否可以执行
我发现在包装器中放置访问检查以确定是否可以执行操作是很自然的。包装代码通常是简单的胶水,可以理解传递给受保护函数的参数,并将这些参数转换为适合做出授权决定的形式。
过滤返回到前端的数据(UI、API 或其他)
我假设您的意思是根据调用者的权限从查询响应中过滤行。例如,如果部门经理查询每个人的工资,则该经理将只返回向他/她报告的人的工资,因为他们无权访问其他人的工资。
对于这种类型的过滤,我从未找到将其作为横切关注点实现的方法。我要么在业务逻辑中加入了过滤,要么退回到一个由于缺乏权限而拒绝执行查询的模型。
我遇到的问题是,要启用过滤,安全代码必须查看返回的数据并能够将权限与之关联。在简单情况下执行此操作似乎需要大量工作,而在复杂情况下则非常麻烦(想象一个返回的数据集是多个数据库操作的连接)。
也就是说,我并不反对内容过滤。我只是还没有看到一个好的解决方案。
【解决方案2】:
Permissions by Activity 是指您拥有的权限和授权 API 正在检查的活动。这与 Roles 和 Permissions 相同,授权是通过检查我们已指定 Role 已授权的业务对象的权限来完成的。这提供了灵活性,因为唯一固定的是权限,但我们可以有不同的角色 - 在数据库中定义完全独立于权限。
将授权逻辑与返回对象进行显示的服务和业务层完全分离的一种方法是使用自定义授权属性。在这些属性中,您可以指定用户需要拥有哪些权限才能在 MVC 控制器中执行操作。
在调用服务或存储库时检索用户有权访问的业务对象并将其用作输入,这是将授权逻辑与服务逻辑分开的好方法。例如 - 我是用户 x,可以访问客户 y、t、g 和 l - 给我所有客户的订单。