【发布时间】:2015-08-01 11:13:36
【问题描述】:
我们有一个 Web Api 2 OData v3 服务,我们需要在该服务上实现相当复杂的授权。我们在客户端代码中使用 Breeze,当 Breeze 的 OData v4 版本发布时,我们会将 API 升级到 OData v4,因此该解决方案需要能够在两个 OData 版本上运行。
这张图给出了我们正在使用的实体模型的一个非常基本的视图(抱歉,没有足够的图像信誉点):
ServiceCompany
|
|
/|\
Manufacturer
|
|
/|\
Site
|
|
/|\
SiteArea -------
| |
| |
/|\ /|\
Equipment Instrument
|
|
/|\
Channel
SiteArea 具有“OperatingFunction”属性 - 这显示了在该站点区域位置发生的制造过程的哪个阶段。
用户可能是
- 处于制造商级别并有权访问其所有站点数据的人员
- 处于制造商级别且有权访问其部分但不是全部 SiteArea 的人员,因此只能访问其 SiteArea 数据的一部分
- ServiceCompany 级别的人有权访问某些制造商,并且在这些制造商中只有某些站点,并且可能只有站点区域的某些操作功能。
将收到对频道数据的请求,我们需要确保只返回或更新(取决于请求类型)允许个人影响的数据。
在初步调查中,实现此功能的明显选择似乎是 QueryInterceptors 和 ChangeInterceptors,这意味着我们可以根据与请求一起发送的声明添加更多过滤器首选项。然而,Query/ChangeInterceptors 似乎是 Wcf 的一部分,而不是 WebApi,除此之外,它们只是 v1-3 Wcf OData 实现的一部分,到目前为止,OData v4 还没有。
当然,我们可以在每个方法中编写过滤器代码,但这看起来确实是一种令人讨厌的方式来实现本质上是一个横切关注点的东西。
我们查看了 EF6 拦截器,但得出的结论是它们离堆栈太远了,理想情况下,我们不想处理 SQL 命令代码本身。
我们已经简要地考虑过是否应该使用基于角色/任务的授权模式,并得出了一个可靠的结论,即这对我们不起作用,因为它对未来的发展来说过于狭窄,并且不适用于我们的扩展计划.
基本上我们得出的结论是,我们需要实现自己的 QueryInterceptorAttribute,但认为在尝试重新发明轮子之前,有必要问问我们是否遗漏了什么。
谢谢。
编辑:我忘了提到另一个选择可能是使用装饰器模式,我们正在使用 Unity 并且可以添加我们需要的功能:Unity Interception
【问题讨论】:
-
是的,自定义 QueryInterceptorAttribute 是在这种情况下继续前进的方式,这将有助于以无缝方式处理所有场景
标签: c# asp.net-web-api authorization odata asp.net-web-api2