-
Working together with AntiForgeryToken and OutputCache on ASP.NET MVC
2 CommentsIf you develop using ASP.NET MVC you’ll probably know the AntiForgeryToken helper method, used as a protection mechanism for cross-site request forgery.
This mechanism consists of two pieces: a cookie (1) and a hidden field included on the form to be submitted (2).
When submitting to a Controller’s Action annotated with the [ValidateAntiForgeryToken] attribute, the MVC framework will compare the values from the Cookie and the Hidden field (which could match partially only) and decide whether the request is valid or not.
The problem with this two-steps mechanism is that it doesn’t get along very well with cache (at least not with caching’s default behavior). Imagine that the action that renders the page with the AntiForgeryToken helper method invocation is marked with the [OutputCache] attribute, this means that unless you take into account cookie generation, you may be returning a cached version of the page (with the hidden field value set) even though the cookie has not been sent to the requesting user.
In order to avoid this issue you can use the VaryByCustom property on the OutputCache attribute:
[OutputCache( Location = OutputCacheLocation.ServerAndClient, Duration = 600, VaryByParam = "none", VaryByCustom = "RequestVerificationTokenCookie")] public ActionResult Index() { return new View(); }
And then program the rule on the global.asax‘s GetVaryByCustomString method:
public override string GetVaryByCustomString(HttpContext context, string custom) { if (custom.Equals("RequestVerificationTokenCookie", StringComparison.OrdinalIgnoreCase)) { string verificationTokenCookieName = context.Request.Cookies .Cast<string>() .FirstOrDefault(cn => cn.StartsWith("__requestverificationtoken", StringComparison.InvariantCultureIgnoreCase)); if (!string.IsNullOrEmpty(verificationTokenCookieName)) { return context.Request.Cookies[verificationTokenCookieName].Value; } } return base.GetVaryByCustomString(context, custom); }
This code checks if the anti-forgery token cookie is sent, and in that case, returns its value that acts as the key for the cached version of the page (which can be safely used since the cookie and the hidden field should have the same partial value); otherwise the base class’ method is invoked which ends up ignoring the cached versions of the page.
Please note that this will generate a lot of cached versions of the page (at least one by user’s session) that can greatly degrade the site performance. In this case I decided to keep the cache for that page as it was the home page and I assumed it would be hit several times by the same user.
-
2 Comments:
You must be logged in to post a comment.
Twitter Trackbacks for Diego Marcet » Working together with AntiForgeryToken and OutputCache on ASP.NET MVC [southworks.net] on Topsy.com said on April 26, 2010:
[...] Diego Marcet » Working together with AntiForgeryToken and OutputCache on ASP.NET MVC blogs.southworks.net/dmarcet/2010/04/26/working-together-with-antiforgerytoken-and-outputcache-on-aspnet-mvc – view page – cached If you develop using ASP.NET MVC you’ll probably know the AntiForgeryToken helper method, used as a protection mechanism for cross-site request Tweets about this link Topsy.Data.Twitter.User['ejadib'] = {“location”:”Argentina”,”photo”:”http://a3.twimg.com/profile_images/54198833/twitter_normal.jpg”,”name”:”Ezequiel Jadib”,”url”:”http://twitter.com/ejadib”,”nick”:”ejadib”,”description”:”Lead Developer at Southworks”,”influence”:”"}; ejadib: “RT @southworks: Blogged: Working together with AntiForgeryToken and OutputCache on ASP.NET MVC http://goo.gl/fb/2YQXk ” 20 minutes ago view tweet retweet Topsy.Data.Twitter.User['southworks'] = {“location”:”",”photo”:”http://a3.twimg.com/profile_images/727738241/SWsmall_normal.png”,”name”:”Southworks”,”url”:”http://twitter.com/southworks”,”nick”:”southworks”,”description”:”Follow the latest technology insights, views, and perspectives from the Southworks staff”,”influence”:”"}; southworks: “Blogged: Working together with AntiForgeryToken and OutputCache on ASP.NET MVC http://goo.gl/fb/2YQXk ” 5 hours ago view tweet retweet Filter tweets [...]
progg.ru said on April 27, 2010:
Совмещение AntiForgeryToken и OutputCache в ASP.NET MVC…
Thank you for submitting this cool story – Trackback from progg.ru…