自己动手实现AntiForgery。
2010-03-14 00:40 姜 萌@cnblogs 阅读(1988) 评论(2) 编辑 收藏 举报为了防止恶意向服务器post数据(比如防止第三方程序模拟post行为)很多web的表单提交使用了特殊的手段,比如qq的登录,论坛的发帖,或是下载网站的放盗链,这些可以统称为AntiForgery。
在asp.net mvc中,我们可以通过Html.AntiForgery()来生成Token,并在相应的action上使用ValidateAntiForgeryTokenAttribute来让框架自动为我们实现AntiForgery(并可以配置提供两个参数Order和Salt(1.0版本))。
但有些时候我们还有其他需求,比如想qq登录那样如果页面数据传送给客户端后如果用户规定时间内不使用就按作废处理,或是不允许用户频繁的想web server post数据。
AntiForgery的实现原理
服务端在处理响应时会做两件事:一是并在response中设置Set-Cookie值为对应值,二是将Ticks与salt联合得到一个Token值写到页面中去。
在客户端再一次向服务端发出http请求时,如果服务器认为需要验证token,就会从post过来的数据中找到ticks(一般由cookie记录)和token(可以使用隐藏域)值(如果没有提供当然就是违规的请求了),并再一次检查ticks与salt的计算结果是否与token相等,如果不相等就是违规的请求。
具体实现
对于.NET,System.Security.Cryptography命名空间下有很多加密/解密算法类,我们可以任选一个对Ticks和Salt进行计算。
用于计算Token的AntiForgeryToken类:
namespace SopacoNetAnc.Mvc.Infrastructure #region Fields #region Properties #endregion #region private Helper Methods |
然后我们可以定义一个类去实现IAuthorizationFilter(对于ASP.NET MVC,如果是java的放到Filter或前端控制器中),然后在OnAuthorization中去校验时间戳是否过期以及Ticks与Token是否相符。
AntiForgeryToken antiForgeryToken = new AntiForgeryToken(salt); //salt自己去规定可以事先弄个Guid long ticks; string formTicks = filterContext.HttpContext.Request.Cookies.Get(AntiForgeryToken.TicksName) != null string formHash = filterContext.HttpContext.Request.Form[AntiForgeryToken.TokenName]; if (string.IsNullOrEmpty(formTicks) || !long.TryParse(formTicks, out ticks) || string.IsNullOrEmpty(formHash)) TimeSpan timeOffset = new TimeSpan(antiForgeryToken.Ticks - ticks); |