1. 请求验证什么?
首先,请看下图:
上图中,是我们常见一个ASP.Net错误提示.由于ASP.Net默认情况是把请求验证(validateRequest)设置是为true,从而使得ASP.Net会对提交的信息进行检查,这在一定程度上有效的阻止了某些危险攻击,比如: 跨站脚本攻击(XSS/CSS).
但是,也存在以下问题:
有时候,我们允许用户输入某些特殊时,如果按照请求验证(validateRequest)默认设置true,那么当用户输入我们允许的特殊字符时,就会出现如上图所示的错误提示,阻止了用户输入.此时,我们必须将请求验证设置为false,才能允许用户输入特殊字符. 可是,一旦把请求验证设置为false,那么ASP.Net就不会对请求验证了,这样其潜在危险就超过了我们的控制范围.
虽然,我们可以在某些页面做特殊处理,以便阻止这些潜在的危险.可以,随着项目扩大,也许要处理的页面就会增长.显然,我们需要灵活、方便、更好的方式进行处理.
2. RequestValidator
那么现在在ASP.NET4就为我们提供了一个可以集中处理的自定义扩展点.
在.Net4中有个System.Web.Util.RequestValidator类,该类是自定义请求验证的基类.我们可以通过实现一个继承自该基类的类,从而实现自己的请求验证过程.
目前,可以验证的请求由枚举类RequestValidatorSource提供,可枚举项具体如下:
1. QueryString 查询字符串。
IsValidRequestString 方法的 collectionKey 参数设置为集合中查询字符串参数的名称。
IsValidRequestString 方法的 value 参数设置为集合中查询字符串参数的值。
2. Form 窗体值。
IsValidRequestString 方法的 collectionKey 参数设置为集合中窗体参数的名称。
IsValidRequestString 方法的 value 参数设置为集合中窗体参数的值。
3. Cookies 请求 Cookie。
IsValidRequestString 方法的 collectionKey 参数设置为集合中的 Cookie 的名称。
IsValidRequestString 方法的 value 参数设置为集合中的值。
4. Files 上载的文件。
IsValidRequestString 方法的 collectionKey 参数设置为集合中已上载文件的名称。
IsValidRequestString 方法的 value 参数设置为集合中已上载文件的值。
5. RawUrl 原始 URL。 (域后的 URL 部分。)
IsValidRequestString 方法的 collectionKey 参数设置为 null。 (RawUrl 不是值集合。)
IsValidRequestString 方法的 value 参数设置为 RawUrl 字段的值。
6. Path 虚拟路径。
IsValidRequestString 方法的 collectionKey 参数设置为 null(Path 不是值的集合)。
IsValidRequestString 方法的 value 参数设置为 Path 字段的值。
7. PathInfo HTTP PathInfo 字符串(URL 路径的扩展)。
IsValidRequestString 方法的 collectionKey 参数设置为 null(PathInfo 不是值的集合)。
IsValidRequestString 方法的 value 参数设置为 PathInfo 字段的值。
8. Headers 请求标头。
IsValidRequestString 方法的 collectionKey 参数设置为集合中 HTTP 头的名称。
IsValidRequestString 方法的 value 参数设置为集合中 HTTP 头的值。
通过以上这些枚举我们基本上就能对常见提交的数据进行统一请求验证处理,比如:忽略某些特殊的数据或者处理某些特殊的数据或者提供一个友好的错误页面等。
3. 实现自定义请求验证
下面演示如何实现一个自定义验证类,对每个查询字符串验证.步骤如下:
1) 继承RequestValidator类,只需要重写IsValidRequestString方法,如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Util;
namespace WebApplication1
{
public class myRequestValidator:RequestValidator
{
protected override bool IsValidRequestString(HttpContext context, string value, RequestValidationSource requestValidationSource, string collectionKey, out int validationFailureIndex)
{
validationFailureIndex = -1;
if (requestValidationSource == RequestValidationSource.QueryString) //对查询字符串进行验证
{
if (value.Contains("<"))//检查是否包含<,当然也可以检查其他特殊符号,或者忽略某些特殊符号.
{
context.Response.Redirect("~/Error.aspx",true);//直接转到自定义的错误页面.
return false;
}
}
return base.IsValidRequestString(context, value, requestValidationSource, collectionKey, out validationFailureIndex);
}
}
}
2) 在web.config中设置请求验证类型为自定义的类型.如下:
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
<httpRuntime requestValidationType="WebApplication1.myRequestValidator" />
</system.web>
</configuration>
现在,我们通过修改url来提交带<特殊符号的页面时,将会被定向到自定义的错误页面,而不是默认错误提示.如下:
如下图所示,并没有出现默认的错误提示,而是到了我们自己提供一个错误页面。
最后,ASP.Net4为我们提供很多扩展点,可以很方便进行扩展,使得我们的应用程序更加灵活可控。