Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/257.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在.net core 2.2中更新模型的正确方法,而不会通过隐藏字段出现任何安全问题_C#_.net_Asp.net Core_.net Core_Asp.net Core 2.2 - Fatal编程技术网

C# 在.net core 2.2中更新模型的正确方法,而不会通过隐藏字段出现任何安全问题

C# 在.net core 2.2中更新模型的正确方法,而不会通过隐藏字段出现任何安全问题,c#,.net,asp.net-core,.net-core,asp.net-core-2.2,C#,.net,Asp.net Core,.net Core,Asp.net Core 2.2,创建脚手架项目(CRUD)时,VisualStudio会创建多个页面,我对编辑页面有一个问题。在这里,它将创建默认布局以更新模型,该模型可以修改以满足您的需要。我看到的问题是,它为您的Id创建了一个隐藏的输入字段。这不是一个安全问题,因为输入控件可以编辑吗?如果对其进行编辑,当您按理论进行保存时,它会更新不同的项目(因此会出现安全问题)?另外,如果我有第二个不应该编辑的字段,例如“CreatedBy”,我应该创建另一个隐藏字段吗?如果此字段也被编辑,我将丢失我的原始CreatedBy user

创建脚手架项目(CRUD)时,VisualStudio会创建多个页面,我对编辑页面有一个问题。在这里,它将创建默认布局以更新模型,该模型可以修改以满足您的需要。我看到的问题是,它为您的Id创建了一个隐藏的输入字段。这不是一个安全问题,因为输入控件可以编辑吗?如果对其进行编辑,当您按理论进行保存时,它会更新不同的项目(因此会出现安全问题)?另外,如果我有第二个不应该编辑的字段,例如“CreatedBy”,我应该创建另一个隐藏字段吗?如果此字段也被编辑,我将丢失我的原始CreatedBy user

此外,如果我删除这些隐藏的输入框以消除安全威胁,我面临的问题是自动验证将失败,因为它不会在模型上保留我的Id或由用户创建的Id。更新时这也是一个问题,因为Id也会丢失。处理这个问题的最好和正确的方法是什么

下面是visual studio在创建脚手架项目(CRUD)时创建的自动代码示例:

。。。
...
无论如何,我知道这是一些基本的东西,我一直在网上寻找答案,但一直没有找到。我已经找到了在验证期间检查特定属性的方法,但这仍然不能确保我不会丢失Id和CreatedBy字段(假设我删除了隐藏的输入)


似乎我唯一的选择就是解决安全问题,但我拒绝相信这是正确的方法。无论如何,谢谢你的帮助

有两种不同的东西:

  • 要更新的Id。

    在更新数据集时,无法阻止将Id发送到服务器,因为HTTP是无状态的。对Session或TempData之类的内容使用变通方法可能会防止出现这种情况,但可能会给使用多个选项卡的用户带来不同的问题(例如,用户加载对象A,然后在新选项卡中加载对象B,然后在选项卡1中保存对象A,这会导致B被覆盖,因为这是会话中加载的最后一个Id)

    这里的解决方案是验证和授权(例如)


  • 过度绑定/“批量分配”

    当客户端发送的信息超过其应发送的信息(例如CreatedBy)时,这就是问题所在。 解决方案是使用只包含可编辑字段的专用ViewModel,或者使用[editable]和[BindNever]等属性。这样,Modelbinding就不会绑定应该是只读的字段。是一篇解释这个问题的博客文章

    因此,最好的方法是在发送到客户端之前删除未使用的隐藏字段(例如CreatedBy)(除非您想在某处显示)。然后,要更新模型,请使用Id从数据库加载数据,更新发布的可编辑属性(以及要设置的其他字段,例如,代码中设置的上次更新日期),然后保存模型


  • 这需要在后端进行验证。您需要编写逻辑,说明“用户是否可以更新此记录?”如果可以,请更新它,否则请告诉用户他们所做的是无效的。@EricMagers所以我应该删除隐藏的输入控件并手动验证它?如果我这样做,我如何知道我正在更新哪个项目,因为绑定模型丢失了Id属性的值?@Lord Link,您可以将Id保留为隐藏输入,但无需保留CreatedBy。如果不需要更新字段,可以在后端获取字段。如果您担心安全性,那么使用AntofgeryToken可能是解决方案:如果他们更改querystring,他们将需要发出一个全新的GET请求,将该请求更改为“stick”。虽然被接受的答案肯定是最佳实践(我很虔诚地遵循它),但您仍然没有解决用户更改值的原始问题。此外,您需要在GET和POST actionsNot true上运行“是否允许用户更改此”逻辑。F12。开发工具。我可以改变任何我想要的,它将被张贴回使用相同的网址。
    ...
    <form method="post">
        <div asp-validation-summary="ModelOnly" class="text-danger"></div>
        <input type="hidden" asp-for="Test.Id" />
        <div class="form-group">
            <label asp-for="Test.Created" class="control-label"></label>
            <input asp-for="Test.Created" class="form-control" />
            <span asp-validation-for="Test.Created" class="text-danger"></span>
        </div>
        <div class="form-group">
            <label asp-for="Test.CreatedBy" class="control-label"></label>
            <input asp-for="Test.CreatedBy" class="form-control" />
            <span asp-validation-for="Test.CreatedBy" class="text-danger"></span>
        </div>
        <div class="form-group">
            <label asp-for="Test.Blahblah" class="control-label"></label>
            <input asp-for="Test.Blahblah" class="form-control" />
            <span asp-validation-for="Test.Blahblah" class="text-danger"></span>
        </div>
        <div class="form-group">
            <input type="submit" value="Save" class="btn btn-primary" />
        </div>
    </form>
    ...