3

情况:

我有一个模型,并且基于用户角色,我希望允许用户仅更新模型的某些部分。假设模型具有三个字段。(我的模型显然比这更复杂)

MyObject
Field1
Field2
Field3

我的视图看起来像这样:

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

忍受我的语法(以及示例的糟糕设计),您可以看到我正在尝试做的事情。在用户发布表单后,我的控制器将获取 MyObject 并将其保存回数据库,我们使用的是 EF。

问题:

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

有更好的吗?

谢谢!

附加信息:

不确定这篇文章是否相关:http: //blog.stevensanderson.com/2008/09/01/prevent-cross-site-request-forgery-csrf-using-aspnet-mvcs-antiforgerytoken-helper/

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

4

3 回答 3

3

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

您决定实现此目的的方法是防止用户使用例如 firebug、F12 开发人员工具或 GreaseMonkey“伪造”响应,并询问了如何做到这一点。

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

防伪令牌用于解决一个单独的问题,即 XSRF。

于 2013-06-04T12:53:08.403 回答
2

使用仅接受应更新的字段的视图模型,然后使用这些值填充模型。您可以使用AutoMapper之类的东西在两者之间进行映射。

于 2013-06-04T12:49:03.443 回答
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
    }
}
于 2013-06-04T13:04:01.180 回答