Breeze js - 如何在保存时验证复杂的业务规则?

时间:2014-09-14 20:06:45

标签: entity-framework validation asp.net-web-api breeze server-side

我熟悉Breeze,因为我认为它可以帮助我处理数据。 Hovewer我最关心的是服务器端的数据验证。我阅读了文档,我知道你应该使用自己的ContextProvider并在里面应用自定义验证。我还阅读了this SO post,其中有人问了类似的问题。

但我认为我遇到了在BeforeSaveEntity函数中无法处理的情况。如果可以,请告诉我如何:

让我们说用户正在尝试更新文章(他自己的文章)。这篇文章有一些ID。 我如何检查用户是否正在更新他的文章而不是其他人(他可以在浏览器中更改文章ID,并且此ID可能是某人的文章ID)。因此,实体仍然有效,但业务规则不允许每个人更改其他用户的文章。

顺便说一句,我想使用EntityFramework和ASP.NET Web Api。

如果只有我可以得到像#34;当前用户"和BeforeSaveEntity函数内的文章ID ...

1 个答案:

答案 0 :(得分:1)

您正确地关注彻底验证客户端保存请求,并且正确地不信任客户端发送的任何内容。

这里有两个问题:谁是用户,他/她是否真的拥有这篇文章。

谁是用户?

Breeze不在身份验证业务之外,我们认为应该通过(大部分)在您在服务器和客户端上编写的应用程序代码外部的方式来解决。

我不会推出自己的安全层。那是在惹麻烦。您可以使用this article by Mike Wasson on Web API security开始研究。

一旦您知道用户,您必须获取有关他或她的特定于应用程序的事实,例如userId以及允许用户执行的操作。我不知道你从哪里得到这些事实,因为这是你的申请特有的。

这是谁的文章?

假设当前userId为12345,更新请求指定了articleId == 42和userId == 12345的文章。显然,本文属于当前用户。这够好吗?我们应该继续保存更改的文章吗?

答案取决于您如何评估恶意客户更新他人文章的后果。我不担心更新Todo(也许我应该?)。如果它涉及银行退出,我不会相信这个请求。

我建议启动单独的DbContext并查询数据库以获取articleId 42。

  

请勿使用DbContext内的ContextProvider中的BeforeSave查询数据库。 DbContext保存来自客户端的修改过的文章。您想要一个单独的DbContext来保存现在每个数据库的实际实体。这些是处于不同状态的独立实体对象。您不能在同一个DbContext中拥有两个具有相同ID的不同文章。

如果查询的文章有userId 12345,您知道客户端发出了有效请求并继续。如果查询文章的userId属性不是12345,则拒绝该请求。

您可以将此失败的请求视为潜在攻击,并将其记录在您记录安全攻击的位置。也许你会监控这个用户和IP地址,谁知道什么。我不在这里。

我可能会以一个神秘的500拒绝这个请求。一个真正的客户不会提出这样的请求而且我不想告诉潜在的攻击者我拒绝它的原因。