MVC中的Form令牌

Ruby中有提供表单的令牌token,struts中也有提供token
今天为了增加表单提交的安全性,于是也想着在mvc里面模拟一个类似token的东西。
做法很简单,写两个filter就可以了,第一个用来产生token,并且将这个token存入Session或者Cookies中,这个filter在action产生前触发,于是生成的页面就可以在表单里面写一个hidden域来存放这个生成的token;另外还要再写一个filter来验证表单提交的时候hidden域中的token跟服务器端保存的token是否一致,这里可以在filter里面重写两个事件,一个在action触发之前判断,一个在action之后,让这个token失效或者重置。

自己实现后再翻查了一下资料,原来ASP.NET MVC从PV5开始就提供了类似这样的token:

先在提交页的表单中写
<%=Html.AntiForgeryToken() %> 
这样就会在客户端页面上生成一个类似

Code


的隐藏域。然后只需要在action头部加上一个系统提供的过滤器,就可以达到目的了,如:

        /// <summary>
        
/// /Home/Login 登陆
        
/// </summary>
        [Microsoft.Web.Mvc.ValidateAntiForgeryToken]
        
public void Login()

其实这种令牌形式只是让安全性稍稍提高了一下,如果别人要外部提交表单,实际上这种方式照样可以被拦截下来。所有Request信息都是可以伪造的,所以最好的方法还是增加底层的安全性,如果用Linq to SQL生成实体的话,那么在model那里实际上就可以做过滤了,如:

    partial class tips : ModelFilter
    {

        
partial void OntitleChanged
        {
            _title 
= FilterContent(_title);
            
if (_title == string.Empty)
            {
                
throw new Exception("not null!");
            }
        }

        
partial void OncontentChanged()
        {
            _content
= FilterJS(_content);
            
if (_content == string.Empty)
            {
                
throw new Exception("not null!");
            }
        }
    }

有一个tips的实体,只需要写一个过滤的基类,然后tips实体继承这个基类就可以了,上面只是简单的把title过滤掉HTML标签,把content过滤掉JS脚本,过滤一般是在Changed事件,如果放在changing事件中,赋值的时候又会把value重新赋给实体了。你也可以根据你的字段来做过滤,如写邮件格式或者电话号码格式的验证,这些格式验证的话就可以写在changing事件。前台验证并不能避免外部提交表单的问题,如果业务不过滤,实体不过滤,很容易就被别人攻击了。很多人主张写一个工具类在业务层那里过滤,需要过滤的地方就调用,使用什么方法都好,因人而异,我个人觉得把实体写完善了,才能减少工作量,因为说不准哪天你就忘记调用你的工具类去过滤了,回过头去找,很累。开blog第一篇,先写到这了。
posted @ 2009-01-03 10:46  b4n73  阅读(564)  评论(1编辑  收藏  举报