Search code examples
c#asp.netantiforgerytoken

AntiforgeryToken & many forms perf


I want to make content in which the delete links are secure. ie.

Row 1

edit delete

Row 2

edit delete

where the delete links are POST links.

To make the delete links POST requests instead of get requests, I'm able to do this with a simple form post paired with an AntiForgeryToken and AntiForgeryToken validation

   using(Html.BeginForm("Delete","Home", FormMethod.Post))
    {
            @Html.AntiForgeryToken()    
            @Html.Hidden("objectId", i)
            <input type="submit" value="Delete" />
    }

c#

 [HttpPost]
 [ValidateAntiForgeryToken]
 public ActionResult Delete(int objectId)
 {
      SafeLogic();
      return View(...);
 }

I also would like to do this with tables, but I have some performance concerns over the generation of so many tokens, eg.

@for (int i = 0; i < 500; i++)
{
  <tr>
  <td> Data Row @i </td>
  <td>    
    using(Html.BeginForm("Index","Home", FormMethod.Post))
    {
            @Html.AntiForgeryToken()    
            @Html.Hidden("objectId", i)

            <input type="image" src="img_delete.gif" alt="Delete" />
    }
  </td>
 
}

How costly is the generation of AntiForgeryTokens? Is the generation of many AntiForgery tokens eg. up to 100, going to be a problem. It is okay to have this many inline html forms?


Solution

  • I had a personal project that needed something like you're doing.

    Instead of having a form for each item that could be removed, I had a single form with a single anti-forgery token.

    @using(Html.BeginForm())
    {
      @Html.AntiForgeryToken()
      {your HTML/Razor}
    }
    

    The delete icon was basically an ajax call that would activate the controller action...

    public JsonResult Delete(int id)
    {
       //delete the item
       if(success)
       {
          return Json(true, JsonRequestBehavior.DenyGet);
       }
       else
       {
          return Json(false, JsonRequestBehavior.DenyGet);
       }
    }
    

    ...and that action would return true or false (success or failure). Acting on that information, I would use jQuery to remove the item from the table (in my case, a formatted table listing). That way I wasn't refreshing the entire page.

    May not work for your implementation but worked out for me.

    I don't necessarily know which is best practice, multiple forms or a single with multiple submit buttons. Some say that you shouldn't do multiple forms if the end action for those forms point to the same action. More info: https://www.google.com/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=html+best+practices+multiple+forms

    It might come down to how pretty or readable you want your html (makes for easier debugging), for instance, if you have a page with a couple of blocks, it probably won't be all that messy. However, think of how your page will be once you have five, or six such blocks.