2009-04-13 72 views
21

在ASP.NET MVC(缺省路由),我想使用URL这样的返回与表单视图编辑顾客:在ASP.NET MVC中比隐藏表单字段更安全吗?

/Customers/Edit/5 

我需要利用CustomerId=5,但我不希望允许客户改变it.Right现在我做隐藏ID使用:

<%= Html.Hidden("CustomerId") %> 

这实现了我想要的东西,但我的印象就是那个隐藏的表单变量是不安全的,可以由最终用户操纵。

那么,允许客户编辑他们的信息而不是他们的ID的最佳方式是什么?

回答

12

我的解决办法加密隐藏字段是从Steven Sanderson's ASP.NET MVC book使用防篡改码。我们的想法是,你创建要防篡改任何隐藏的表单字段的哈希:

<%= Html.Hidden("CustomerId") %> 
<%= Html.Hidden("CustomerIdHash") %> 

当提交表单时,史蒂芬的代码然后计算客户编号的另一个哈希,使某些它等于CustomerIdHash。如果确实如此,则不会发生篡改。这是很棒的代码,并且值得这本书的价格。

6

你不会在浏览器端做任何真正的安全。您可以将客户ID放入查询字符串中,但服务器应验证他们是否真的被允许编辑该客户。如果不是,则返回错误。

10

在显示相关视图之前,检查控制器操作(/ Customers/Edit)中的权限。请注意,这里的问题与您的隐藏字段完全不同:用户只需在浏览器中输入“http://yoursite.com/Customers/Edit/10”即可。因此,无论他如何调用该操作,您都必须检查您的操作是否允许用户编辑请求的客户的详细信息。

+1

我看到如何配置控制器操作,以便只有授权用户才能看到特定ID的视图,但我看不到如何防止用户更改该ID。例如,用户可能被授权查看/ Customers/Edit/10,但是他们可以在提交表单时更改ID并编辑他们未被授权查看的ID(例如/ Customers/Edit/11)。我想我需要检查提交的表单,以确保ID是我发送给他们的第一位。 – royco 2009-04-20 05:37:58

+1

您必须检查当前登录的用户是否有权查看/编辑所请求的ID。因此,在您的控制器操作中,您检索用户名(例如使用Thread.CurrentPrincipal.Identity.Name),并检查您的数据库是否允许此用户执行他尝试执行的操作(根据请求的操作查看或编辑)。因此,如果用户更改了ID,他仍然无法查看\编辑他不允许的内容。实际上,他甚至没有理由尝试改变ID ... – 2009-04-20 07:32:13

1

有两个方面。我不确定你是直接询问的,但它们都很重要:

  • 对于任何给定的用户,他们可能不被允许编辑所有客户。因此,正如德米特里所建议的,您的表单发布的控制器操作需要查看他们正尝试编辑的客户,并验证登录的用户实际上是否允许编辑该客户。您可能还想在首先生成编辑表单的控制器操作中执行类似的检查,如果不允许编辑请求的客户,甚至不会让他们进入表单。
  • 对于给定的用户和给定的客户,您可能不希望用户能够更改客户ID。如果您在POST控制器操作中使用UpdateModel方法,则需要使用属性白名单参数并排除ID属性,以便用户不更改ID。即使他们更改隐藏字段的值,UpdateModel也会通过白名单忽略已更改的值。
2

我有同样的问题,我相信解决方案涉及使用代理键。在每个有ID列的表中,我还添加一个Guid(SQL服务器中的uniqueidentifier)的Key列。现在,当进行连接或任何内部逻辑时,我使用该ID,但控制器都使用密钥。既然是Guid,很难猜出另一张唱片的Guid是什么。

可替换地(或附加于上述),你可以根据This article

3

防篡改隐藏字段都很好,但仍然通过默默无闻的安全。通过保护控制器和操作来保证网站,尤其是MVC是最好的。然后用户可以篡改他们想要的一切,而且他们不会去任何地方。