2013-06-04 35 views
3

状况:.NET MVC防止伪造的POST

我有一个模型,并根据用户的角色我想允许用户只更新模型的某些部分。比方说模型有三个领域。 (我的模型显然是比这更复杂)

MyObject 
Field1 
Field2 
Field3 

我的视图看起来是这样的:

Html.TextBoxFor(@Model.Field1) 
Html.TextBoxFor(@Model.Field2) 
@if(UserIsAdmin()) 
    Html.TextBoxFor(@Model.Field3) 
else 
    @Model.Field3 

与我的语法(和示例的设计不良)轴承,您可以看到我正在尝试做什么。当用户发布表单时,我的控制器只需要MyObject并将其保存回数据库,我们正在使用EF。

问题:

我的问题是,有没有办法从锻造POST能够保存数据,他/她不应该能够阻止用户。我目前的想法是检查控制器,看看用户是否修改了他不应该有的值。或者我可以单独保存字段,但都不是一个简便的解决方案。

有更好的吗?

谢谢!

附加信息:如果

不知道这是ARTICAL相关可言:http://blog.stevensanderson.com/2008/09/01/prevent-cross-site-request-forgery-csrf-using-aspnet-mvcs-antiforgerytoken-helper/

所有三个字段是从同一个数据库表,我用EF来获取和保存的实体。

回答

2

使用仅接受应更新的字段的视图模型,然后用这些值填充模型。你可以使用诸如AutoMapper之类的东西来映射这两者。

3

您想确保用户只能更新允许的字段。

您确定实现此目的的方法是防止用户使用例如“伪造”应答。萤火虫或F12开发人员工具或GreaseMonkey,并询问如何执行此操作。

但是正确/最好的方法是检查用户试图更新哪些字段,并且只更新他允许更新的那些字段。那么不管他们是否伪造请求,他们仍然不能访问他们不应该的任何东西。换句话说,在访问点检查访问权限。

防伪标记有解决单独的问题,即XSRF。

+0

所以你是说,防止用户“锻造“回应不会阻止不受欢迎的行为?我明白你的意思,这不是最好的方法。 – kralco626

+0

为了回答我自己的问题,我猜不是,因为用户可以在cookie中创建值并形成匹配。 – kralco626

1

我目前的想法是做一个检查控制器,看看用户是否修改了他不应该有的值。或者我可以单独保存字段,但都不是一个简便的解决方案。

你在这个想法的正确轨道上。一个典型的Add()操作是这样的:

public class FooController : Controller 
{ 
    public ActionResult Add(FooViewModel viewModel) 
    { 
     if (ModelState.IsValid) 
     { 
      FooDataModel dataModel = FooMapper.MapToDataModel(viewModel, User); 
      FooRepository.Add(dataModel); 
     } 
    } 
} 

像@VimalStan说,你FooViewModel是那么只包含您想要让用户更新领域的典范。另外这仍然不能解决你的问题,这应该在你的映射器来完成(在这种情况下FooMapper),并且仍然检查每一个字段作为@Ben建议:

public static class FooMapper 
{ 
    public static FooDataModel Map(FooViewModel viewModel, IPrincipal user) 
    { 
     var dataModel = new FooDataModel(); 

     dataModel.Field1 = viewModel.Field1; 
     dataModel.Field2 = viewModel.Field2; 

     if (IsAllowedToUpdateField3(user)) 
     { 
      dataModel.Field3 = viewModel.Field3; 
     } 

     return dataModel; 
    } 

    public static bool IsAllowedToUpdateField3(IPrincipal user) 
    { 
     return false; // your logic 
    } 
}