防伪令牌的思想是防止攻击者代表用户生成 POST / GET 请求。这就是为什么我们为每个 POST / GET 请求添加一些特殊的东西,这是攻击者不知道的。
自定义防伪的最简单实现如下所示。它与 ValidateAntiForgeryToken 一样安全。
public class ProfileController : AuthorizedAccessController
{
// GET
public ActionResult Details(int userId)
{
User user = this.Entities.User.First(u => u.Id == userId);
this.Session["ProfilePageAntiforgery"] = Guid.NewGuid(); // use RandomNumberGenerator to generate strong token
this.ViewBag.ProfilePageAntiforgery = this.Session["ProfilePageAntiforgery"];
return View(user);
}
public ActionResult DeleteMyProfile(int userId, string profilePageAntiforgery)
{
if ((string)this.Session["ProfilePageAntiforgery"] != profilePageAntiforgery)
{
return this.RedirectToAction("Details", new { userId });
}
User user = this.Entities.User.First(u => u.Id == userId);
this.Entities.User.Remove(user);
this.Entities.SaveChanges();
return this.RedirectToAction("ProfileDeleted");
}
}
看法:
<div>
@Html.ActionLink("Delete my profile", "DeleteMyProfile", new {userId = this.Model.Id, profilePageAntiforgery = this.ViewBag.ProfilePageAntiforgery })
</div>
从中制作自定义属性是一个技术问题。让我们说一个属性将令牌存储在 session 和 viewbag 中,另一个用于验证。
如果使用 Session 不好(Web 农场等),您可以简单地用 DB 或其他存储替换它。