让我来详细讲解一下“Community Server专题三:HttpModule”的完整攻略。
标题
1. 什么是HttpModule?
HTTP模块(HttpModule)是用于扩展 ASP.NET Web 应用程序处理请求管道的一个组件。通过使用HTTP模块,您可以在请求处理期间介入请求管道,并检查或修改进入的请求、出站的响应或双方。HttpModule 常见的使用场景是在请求开始时记录日志,在请求结束时进行性能统计等。
2. 如何使用HttpModule?
使用HttpModule非常简单。我们只需要编写一个类实现IHttpModule
接口即可。我们需要实现的是Init()
和Dispose()
方法。
public class SampleHttpModule : IHttpModule
{
public void Init(HttpApplication context)
{
//在这里进行模块的初始化操作
}
public void Dispose()
{
//在这里进行模块的清理操作
}
}
当我们实现了一个HttpModule后,我们还需要在Web.config
文件中将该模块添加到
<configuration>
<system.web>
<httpModules>
<add name="SampleHttpModule" type="SampleHttpModule"/>
</httpModules>
</system.web>
</configuration>
这样,我们就完成了一个简单的HttpModule的基本实现和配置。
3. HttpModule的示例
接下来,我们通过两个示例来演示HttpModule的应用。
示例一:记录访问日志
public class LogHttpModule : IHttpModule
{
private string logFilePath = @"d:\log.txt";
public void Init(HttpApplication context)
{
context.BeginRequest += new EventHandler(BeginRequestHandler);
context.PreRequestHandlerExecute+= new EventHandler(PreRequestHandlerExecuteHandler);
context.EndRequest += new EventHandler(EndRequestHandler);
}
private void BeginRequestHandler(object sender, EventArgs e)
{
HttpApplication app = (HttpApplication)sender;
HttpContext context = app.Context;
string url = context.Request.Url.ToString();
string method = context.Request.HttpMethod;
string query = context.Request.QueryString.ToString();
File.AppendAllText(logFilePath, string.Format("[{0}] Begin {1} {2} {3}{4}", DateTime.Now, method, url, query, Environment.NewLine));
}
private void PreRequestHandlerExecuteHandler(object sender, EventArgs e)
{
HttpApplication app = (HttpApplication)sender;
HttpContext context = app.Context;
string url = context.Request.Url.ToString();
string method = context.Request.HttpMethod;
string query = context.Request.QueryString.ToString();
File.AppendAllText(logFilePath, string.Format("[{0}] Execute {1} {2} {3}{4}", DateTime.Now, method, url, query, Environment.NewLine));
}
private void EndRequestHandler(object sender, EventArgs e)
{
HttpApplication app = (HttpApplication)sender;
HttpContext context = app.Context;
string url = context.Request.Url.ToString();
string method = context.Request.HttpMethod;
File.AppendAllText(logFilePath, string.Format("[{0}] End {1} {2}{3}", DateTime.Now, method, url, Environment.NewLine));
}
public void Dispose()
{
}
}
在这个示例中,我们实现了一个记录访问日志的HttpModule。在BeginRequest事件中记录开始处理请求的日志,在PreRequestHandlerExecute事件中记录正在处理请求的日志,在EndRequest事件中记录完成请求处理的日志。我们通过File.AppendAllText()
将日志内容写入到指定的文件中。
我们还需要在Web.config文件中配置该模块。将下列代码添加到
<add name="LogHttpModule" type="LogHttpModule"/>
示例二:防止SQL注入
public class SqlInjectionHttpModule : IHttpModule
{
public void Init(HttpApplication context)
{
context.PreRequestHandlerExecute += new EventHandler(PreRequestHandlerExecuteHandler);
}
private void PreRequestHandlerExecuteHandler(object sender, EventArgs e)
{
HttpApplication app = (HttpApplication)sender;
HttpContext context = app.Context;
foreach (string key in context.Request.QueryString.Keys)
{
if (HasSqlKeyWord(context.Request.QueryString[key]))
{
context.Response.StatusCode = 500;
context.Response.Write("Sql Injection Detected!");
context.Response.End();
return;
}
}
foreach (string key in context.Request.Form.Keys)
{
if (HasSqlKeyWord(context.Request.Form[key]))
{
context.Response.StatusCode = 500;
context.Response.Write("Sql Injection Detected!");
context.Response.End();
return;
}
}
}
private bool HasSqlKeyWord(string input)
{
string[] sqlKeyWords = new string[] {"select", "insert", "update", "delete", "create", "drop", "truncate", "exec", "declare"};
foreach (string sqlKeyWord in sqlKeyWords)
{
if(input.ToLower().IndexOf(sqlKeyWord) >= 0)
{
return true;
}
}
return false;
}
public void Dispose()
{
}
}
在这个示例中,我们实现了一个防止SQL注入攻击的HttpModule。在PreRequestHandlerExecute事件中,我们遍历查询字符串和表单数据,判断它们是否包含SQL语句中的关键词,如果包含,我们就返回500和一个提示信息,直接结束响应。
我们还需要在Web.config文件中配置该模块。将下列代码添加到
<add name="SqlInjectionHttpModule" type="SqlInjectionHttpModule"/>
4. HttpModule的注意事项
在编写HttpModule时,需要注意以下几点:
- HttpModule仅对ASP.NET应用程序生效,不适用于静态文件。
- 在BeginRequest事件处理程序执行之前,HttpModule没有HttpApplication对象的引用,同时也不能访问Session、Application或用户标识(通过HttpContext.User属性)。
- 在BeginRequest事件处理程序执行后,HttpModule就能够访问Session,但尚不能访问Application或HttpContext.User属性。
- 有些事件(例如AuthenticateRequest)只有在模块为Windows身份验证模式配置时才会发生。因此,如果应用程序采用表单验证,则不会触发AuthenticateRequest事件。
- 模块的顺序很重要。在一次请求期间,每个模块都按照在Web.config文件中的排列顺序进行反序列化和实例化。因此,在编写用户模块时,应该考虑这个问题。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Community Server专题三:HttpModule - Python技术站