如何通过基于用户的授权最小化到SQL的往返?

时间:2013-07-24 00:01:49

标签: sql postgresql model-view-controller authorization role-base-authorization

上下文:由SQL DB支持的MVC Web服务。假设我在我的数据库中有一个用户关系,以及一组通过一系列FK引用它的关系。例如,假设我有表格:

sales_people
car_dealership
cars

销售人员属于某个汽车经销商,汽车也是如此。销售人员应该只能看到属于其特定经销商的汽车。我在这里有几个选择:

我可以将授权业务逻辑烘焙到SQL查询中:

SELECT *
FROM cars as c, sales_people AS sp, car_dealerships AS cd
WHERE where c.dealership_id = cd.id
AND sp.dealership_id = cd.id
AND sp.id = ?
AND c.id = ?

假设调用者已经验证了sales_people id是合法的并且防止了该id的琐碎欺骗,那么上面的查询将阻止用户获得不是他的汽车。只要连接不是太大,这可能会扩展到任意数量的表。

上行?一个DB调用。

下行?

  • 这里的授权业务逻辑非常基础。其中一个表引用的用户?当然,你可以通过。但是,假设我必须拥有更复杂的访问规则。通过一个简单的查询,它们可能根本就不可行。
  • 很难判断用户是否请求了未经授权的行,或者该行是否已获得授权但实际上并不存在,因此会使错误报告变得棘手。您不知道是否应该报告200或403(尽管在这些情况下您可能希望始终使用200以防止向攻击者暴露过多信息)。

我看到的另一个选项是在事实之前或之后进行额外查询以验证该用户确实可以访问的数据。例如。获取销售人员有权获得的汽车ID列表,然后对该子集执行查询,或者完全相反。

显而易见的好处是,我可以在业务层中进行更多调用并运行更多逻辑,并且可以随心所欲地进行复杂化。

缺点是我将产生更多数据库流量,这可能是一个交易破坏者,具体取决于请求的频率。

我可能在这里缺少其他一些选项,我很想知道你之前是如何解决这个问题的。有更好的方法吗?

2 个答案:

答案 0 :(得分:3)

我认为作为一般规则,您应该使代码在逻辑上表现,然后以其他方式扩展性能,例如:更强大的数据库或缓存结果。

对于我的应用程序,我使用多个查询。我已经定时了我们的系统,5-10次往返时间不到1毫秒。这对我来说已经足够了。我见过其他人创建复杂的存储过程来做他们想做的一切。结果是他们可以从数据库中返回403或404之类的内容。

我个人更愿意多次访问数据库,以使代码更清晰,更易于阅读。如果您的负载不是太大,尤其如此。硬件很便宜,但你的时间不是。

答案 1 :(得分:0)

我想在调试其中一些问题之后添加另一个意见。

很高兴告诉用户(或应用程序代码)究竟出了什么问题。我现在通常的做法是从SQL返回所有相关的安全信息,然后在应用程序中进行检查。通过这种方式,可以往返数据库,您可以从代码中提供非常详细的信息,例如: “你再也无法进入这家经销店了。”或“这辆车已被删除。”。