HttpModule Implementation
HttpModules provide functionality similar to ISAPI Filters in the ASP.NET pipeline. Development typically follows these steps:
- Create a class implementing IHttpModule interface
- Implement Init method with event registration
- Define event handler methods
- Optionally implement Dispose method for cleanup
- Register the class in Web.config
Here's a basic HttpModule example that hooks into request lifecycle events:
using System;
using System.Web;
namespace RequestInterceptor
{
public class RequestLogger : IHttpModule
{
public void Init(HttpApplication context)
{
context.BeginRequest += OnRequestStart;
context.EndRequest += OnRequestComplete;
}
private void OnRequestStart(object sender, EventArgs e)
{
HttpApplication app = (HttpApplication)sender;
HttpResponse response = app.Context.Response;
response.Write("<div>Request Processing Started</div>");
}
private void OnRequestComplete(object sender, EventArgs e)
{
HttpApplication app = (HttpApplication)sender;
HttpResponse response = app.Context.Response;
response.Write("<div>Request Processing Completed</div>");
}
public void Dispose() { }
}
}
The System.Web namesapce is essential as it contains HttpApplication, HttpContext, and HttpResponse classes. The module registers handlers for BeginRequest and EndRequest events.
Registration in Web.config:
<configuration>
<system.web>
<httpModules>
<add name="RequestLogger" type="RequestInterceptor.RequestLogger, RequestInterceptor" />
</httpModules>
</system.web>
</configuration>
HTTP Pipeline Event Sequence
HttpModules interact with the HTTP pipeline through HttpApplication events:
- BeginRequest
- AuthenticateRequest
- AuthorizeRequest
- ResolveRequestCache
- AcquireRequestState
- PreRequestHandlerExecute
- PostRequestHandlerExecute
- ReleaseRequestState
- UpdateRequestCache
- EndRequest
These events correspond to Global.asax application events. Understanding the execution order is crucial since server objeects have different states at each stage.
Authorization Module Implementation
HttpModules effectively decouple cross-cutting concerns like authorization from business logic. Here's an authorization filter implemantation:
using System;
using System.Web;
namespace SecurityModule
{
public class AuthorizationFilter : IHttpModule
{
public void Init(HttpApplication context)
{
context.AcquireRequestState += CheckAccessRights;
}
private void CheckAccessRights(object sender, EventArgs e)
{
HttpApplication app = (HttpApplication)sender;
User currentUser = app.Context.Session["CurrentUser"] as User;
string requestPath = app.Context.Request.Path;
Module requestedModule = ModuleResolver.GetModuleFromUrl(requestPath);
if (!AccessValidator.HasPermission(currentUser, requestedModule))
{
app.Context.Server.Transfer("/AccessDenied.aspx");
}
}
public void Dispose() { }
}
}
public class AccessValidator
{
public static bool HasPermission(User user, Module module)
{
// Validate user permissions for the module
return user != null && user.HasAccess(module);
}
}
This approach centralizes authorization logic, eliminating repetitive permission checks across individual pages. The module intercepts requests during the AcquireRequestState phase when session data becomes available.
HttpModules provide powerful interception capabilities for implementing cross-cutting concerns including authentication, logging, compression, and custom header manipulation.