Encryption 如何确保Asp.Net核心MVC中编辑表单的隐藏字段中的EntityId的安全?

Encryption 如何确保Asp.Net核心MVC中编辑表单的隐藏字段中的EntityId的安全?,encryption,asp.net-core,asp.net-core-mvc,Encryption,Asp.net Core,Asp.net Core Mvc,我想创建一个表单,用于使用EntityFramework核心编辑数据库中的某个实体(例如一篇文章) 我想在从浏览器重写为另一个值之前保护隐藏字段中的值。我想在更新之前检查一下用户权限,但是我想创建一些加密/签名之类的东西 如何对PostId进行加密或签名,并在控制器中对其进行解密或验证 我创建了编辑帖子的示例表单,如下所示: 实体-员额: public class Post { [Key] public int PostId { get; set; } [Required] [

我想创建一个表单,用于使用EntityFramework核心编辑数据库中的某个实体(例如一篇文章)

我想在从浏览器重写为另一个值之前保护隐藏字段中的值。我想在更新之前检查一下用户权限,但是我想创建一些加密/签名之类的东西

如何对PostId进行加密或签名,并在控制器中对其进行解密或验证

我创建了编辑帖子的示例表单,如下所示:

实体-员额:

public class Post
{
  [Key]
  public int PostId { get; set; }

  [Required]
  [StringLength(40)]
  public string Title { get; set; }
}
控制器-具有编辑方法的PostsController:

[HttpPost]
[ValidateAntiForgeryToken]
    public async Task<IActionResult> Edit(int id, [Bind("PostId,Title")] Post post)
    {
        if (ModelState.IsValid)
        {
          //Update method
        }
        return View(post);
    }
[HttpPost]
[ValidateAntiForgeryToken]
公共异步任务编辑(int-id,[Bind(“PostId,Title”)]Post-Post)
{
if(ModelState.IsValid)
{
//更新方法
}
返回视图(post);
}
编辑表格:

@model EFGetStarted.AspNetCore.NewDb.Models.Post

@{
    ViewBag.Title = "Edit Post";
}

<h2>@ViewData["Title"]</h2>

<form asp-controller="Posts" asp-action="Edit" method="post" asp-antiforgery="true" class="form-horizontal" role="form">
    <div class="form-horizontal">

        <div asp-validation-summary="All" class="text-danger"></div>

        <input asp-for="PostId" type="hidden" />

        <div class="form-group">
            <label asp-for="Title" class="col-md-2 control-label"></label>
            <div class="col-md-10">
                <input asp-for="Title" class="form-control" />
                <span asp-validation-for="Title" class="text-danger"></span>
            </div>
        </div>

        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Edit" class="btn btn-default" />
            </div>
        </div>
    </div>
</form>
@model EFGetStarted.AspNetCore.NewDb.Models.Post
@{
ViewBag.Title=“编辑帖子”;
}
@ViewData[“标题”]

通过加密,你不会得到任何真正的商业价值,如果目的是阻止一个用户编辑/修改他无权访问的帖子,你应该遵循“从不信任客户端”的原则在后端进行,并始终在服务器上验证输入

最简单的方法是只使用发布的模型中的post ID,并验证用户是否有修改它的权限。为此,新的基于策略的系统提供了良好的文档记录,可用于验证权限

完成后,将接管值并保存更改


另外,您不应该在视图中使用持久性模型,当您更改数据库布局和导航属性时,它们很容易破坏API或表单,可能会导致问题(循环引用等);特别是以后,当实现延迟加载时(延迟加载不能异步发生,因为它在属性中,因此db调用将阻止线程)。

通过加密它,您不会获得任何真正的业务价值,如果目的是防止一个用户编辑/修改他无权访问的帖子,您应该在后端按照“从不信任客户机”原则,始终在服务器上验证输入

最简单的方法是只使用模型中发布的post ID,并验证用户是否有修改权限。为此,新的基于策略的系统提供了详细的文档,可用于验证权限

完成后,将接管值并保存更改


另外,您不应该在视图中使用持久性模型,当您更改数据库布局和导航属性时,持久性模型很容易破坏API或表单,这可能会导致问题(循环引用等);特别是在以后,当实现延迟加载时(延迟加载不能异步进行,因为它位于属性内部,因此db调用将阻止线程).

看看Sergey Akopov,他在那里提出了一种在ASP.NET MVC中处理这种情况的机制。他的解决方案是编写一个Html帮助程序,可以在视图中调用它来生成一个隐藏的输入,以伴随您希望“防篡改”的每个输入“。此隐藏输入包含要防篡改的值的加密副本。发布表单时,服务器会检查发布的值和附带的加密值是否仍然匹配-他会写入一个筛选器属性,该属性将应用于相应的控制器操作以执行此检查。这会添加一层额外的“从不信任客户”安全


另一个例子(在评论中)围绕这种方法固有的潜在安全缺陷进行了有趣的讨论——主要的一个问题是一个有决心的攻击者可能“农场”"安全字段和来自编辑会话的加密值的有效组合,然后使用这些托管值在将来的编辑中发布篡改数据。

看看Sergey Akopov的文章,他在其中提出了一种在ASP.NET MVC中处理这种情况的机制。他的解决方案是编写一个Html帮助程序,可以在ASP.NET MVC中调用您的视图将生成一个隐藏输入,以伴随您希望“防篡改”的每个输入。此隐藏输入包含要防篡改的值的加密副本。发布表单时,服务器会检查发布的值和附带的加密值是否仍然匹配-他会写入一个筛选器属性,该属性将应用于相应的控制器操作以执行此检查。这会添加一层额外的“从不信任客户”安全


另一个例子(在评论中)围绕这种方法固有的潜在安全缺陷进行了有趣的讨论——主要的一个问题是一个有决心的攻击者可能“农场”"安全字段和编辑会话中加密值的有效组合,然后使用这些托管值在未来编辑中发布篡改数据。

为什么要加密它?我看不到这背后有什么有效的业务逻辑,只是没有任何意义。只需遵循简单的原则:永远不要信任客户端。使用Id要从数据库检索原始数据,请检查其是否为同一用户或他是否具有权限(您也可以使用基于资源的策略授权,如下所述)另外,请注意,不要将持久性模型传递给视图,从长远来看,这不会有好的结果,特别是当您有导航属性时。为什么要对其进行加密?我看不到这背后有有效的业务逻辑,这没有多大意义。只需遵循一个简单的原则:永远不要信任客户端。使用Id来检索它从数据库中删除原始数据,检查其是否为同一用户或他是否具有权限(您也可以