c# - 在.net core 2.2中更新模型的正确方法,而不会通过隐藏字段出现任何安全问题
问题描述
创建脚手架项目 (CRUD) 时,Visual Studio 会创建多个页面,我对编辑页面有疑问。在这里,它创建默认布局以更新您的模型,可以对其进行修改以满足您的需求。我看到的问题是它为您的 ID 创建了一个隐藏的输入字段。由于可以编辑输入控件,这不是安全问题吗?如果对此进行了编辑,当您按理论保存时,它会更新不同的项目(因此存在安全问题)?另外,如果我有第二个不应编辑的字段,例如“CreatedBy”,我是否应该创建另一个隐藏字段?如果此字段也被编辑,我将失去我原来的 CreatedBy 用户。
此外,如果我删除这些隐藏的输入框以消除安全威胁,我面临的问题是自动验证将失败,因为它不会在模型上保留我的 Id 或 CreatedBy 用户。这也是更新时的一个问题,因为 Id 也会丢失。处理此问题的最佳和正确方法是什么?
下面是创建脚手架项目 (CRUD) 时由 Visual Studio 创建的自动代码示例:
...
<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>
...
无论如何,我知道这是基本的东西,我一直在网上寻找答案,但一直找不到。我找到了在验证期间检查特定属性的方法,但这仍然不能确保我不会丢失 Id 和 CreatedBy 字段,假设我删除了隐藏的输入。
似乎我唯一的选择是遇到安全问题,但我拒绝相信这是正确的方法。无论如何感谢您的帮助!
解决方案
有2个不同的东西:
要更新的 ID。
更新数据集时无法阻止将 Id 发送到服务器,因为 HTTP 是无状态的。使用诸如 Session 或 TempData 之类的解决方法可能会阻止这种情况,但可能会给使用多个选项卡的用户带来不同的问题(例如,用户加载对象 A,然后在新选项卡中加载对象 B,然后将对象 A 保存在选项卡 1 中,这会导致 B被覆盖,因为这是会话中加载的最后一个 Id)。
这里的解决方案是验证和授权(例如基于资源的授权)。
过度绑定/“批量分配”
当客户端发送的信息超出其应有的信息(例如 CreatedBy)时,就会出现此问题。解决方案是使用仅包含可编辑字段的专用 ViewModel 或使用 [Editable] 和 [BindNever] 等属性。这样 Modelbinding 不会绑定应该是只读的字段。这是一篇解释该问题的博文。
所以最好的方法是在发送给客户端之前删除未使用的隐藏字段(例如 CreatedBy)(除非您想在某处显示它)。然后要更新模型,您使用 Id 从数据库加载数据,更新发布的可编辑属性(以及您要设置的其他字段,例如代码中设置的最后更新日期),然后保存模型。
推荐阅读
- c++ - 为什么 std::string 和 std::vector 没有按照我的预期传递给我的构造函数?
- javascript - 异步web API调用成功函数不返回数据集
- spring-boot - 使用 SpringBoot 登录
- python - 用于多步时间序列预测的 LSTM 神经网络
- service - 如何从 cloudera manager 中删除已安装的 csd 文件
- r - 过滤较大数据帧的搜索条件失败
- ios - iOS(Swift):按下时使 UIButton 变暗
- r - 创建交互项的问题
- xquery - xQuery 中的元素构造函数是什么?
- typescript - 如何为类型创建文字值?