URL Rewriting

Introduction
URL rewriting is a process of redirecting the requested resource to the other resource without changing requested URL. It means the result of requested URL will be furnished from the location whose URL might be different than the requested one.

Generally all the requested URLs are mapped with physical file (ex .aspx file) which contains the requested resource.

There are many scenarios where we might need to implement this concept.

1. When user tries to access this page, virtual path mapped with this physical location get furnished if available. This result in broken link if requested page/resource is not found at specified location. This usually happens when pages get moved doe to site restructuring. Using Rewrite we can simply redirect the request to actual moved location.

2. Most of the times developer stores required information as URL parameters, this makes URLs harder to remember and error some to type. Also key, value pairs used for URL query string makes no sense for end user to type as he/she might not be aware of its use.

Example:

Consider a page displaying employee data having URL http://site.com/empdetail.aspx?id=1. Using Rewriting we effectively make this URL more meaningful as http://site.com/employees/username. This adds more usability for end user as he/she can just type http://site.com/employees to list all the employees or can use http://site.com/employees/a-b to list all employees name starting with a to b only.

This concept can also be used creatively for culture based page rendering. Like MSDN pages every page can be followed by the culture name like http://site.com/en-us/employees/username. This makes the URL more hackable to use different culture for same page.

3. Creating robust site structured URL routing engine. Web application can maintain the desired URLs with key notations and actual URL to redirect to.

URL Request handling
Following steps elaborates the basic request (URL) handling.

1. Accepting request

Every request made to server first gets captured by IIS. IIS 6 uses kernel mode device driver called HTTP Protocol Stack (namely HTTP.sys) to listen HTTP request. Earlier versions of IIS use windows sockets (Winsock) for same purpose.

2. Request Handling

Once IIS receives the request it gets processed though ISAPI (Internet Service Application Programming Interface) extensions and ISAPI filters. ISAPI extensions create the desired response to send to end user, whereas ISAPI filter handles all the events to control the processing of request.

ISAPI extensions are mapped to particular file extensions that it need to handle in IIS. Depending on the file extension the appropriate ISAPI extension gets loaded. For example to handle classic asp file IIS uses asp.dll and for ASP.Net page requests it uses aspnet_ISAPI.dll. Along with this ISPAI filter also gets loaded which is responsible for Authentication, Authorization, Logging, Monitoring and URL rewrite. ISAPI filter invokes the events to control this request and can manipulate it at any time needed.

ISAPI extension and ISAPI filter are unmanaged code and need to be implemented at IIS side. However .Net Framework provides the exact functionality for web application using ASP.Net Engine. Once request is recognized IIS sends it to ASP.Net Engine through aspnet_ISAPI.dll

3. ASP.Net Engine

ASP.Net Engine offers the similar functionality as ISAPI filter and ISAPI extension through HTTP Module and HTTP Handler. HTTP Module manages all the events for lifecycle of the request and HTTP handler retrieves the response to load from the specified location.

Source: MSDN

ASP.Net Engine allows intercepting request to other location / URL at both HTTP Module and HTTP Handler as described below in Implementation section.

Implementation

Implementation of URL Rewrite is very easy and can be done using System.Web.HttpContext class. HttpContext (Namespace: System.Web [more info: http://msdn.microsoft.com/en-us/library/system.web.httpcontext.aspx]) is a class which gets created per request to encapsulate all the HTTP specific information like Request, Response, Server Information, Cache and commonly used Current static property that retrieves current HTTP request object.
HttpContext class provides a method RewritePath. This method allows requested URL to differ from the requested one. This call intercepts path in cookie-less state.

URL rewriting can be implemented using following ways:
1. Using HTTP Module
2. Using HTTP Handler

1. HTTP Module

ASP.Net provides built-in HTTP Modules that control the request during its lifecycle. Custom HTTP Module can be implemented in ASP.Net application to manage this lifecycle. ASP.NETprovides IHttpModule to create custom Http Modules which need to be registered in configuration file of the application being using it.

HTTP Module plays important role in authentication and authorization of request so it’s important to decide at which point URL Rewrite can be implemented. In the lifecycle of request BeginRequest is the very first event gets fire before authorization and authentication. It’s always recommended to rewrite the path in BeginRequest or AuthenticateRequest so that to ensure the integrity of the authentication and authorization.

Followings are the in-built modules used by ASP.Net engine for authentication and authorization of request.

I. FormsAuthenticationModule:

Determines if user is authenticated using AuthenticateRequest event handler.
II. FileAuthorizationMoudle:

Determines if user account in which current application is running has adequate authorization when using Windows Authentication using AuthorizeRequest event handler.

III. UrlAuthorizationModule:

This module is configuration through web.config’s location section and checks if requested URL can be accessed for requester using AuthorizeRequest event handler.
Execution of these events is as follows:

Security perspective there are three approaches that needs to be considered while deciding event when rewrite the path.

  • No Authentication: In this case you can rewrite path in any of BeginRequest, AuthenticateRequest or AuthorizeRequest event of application.
  • Form Authentication: In this case path should be rewritten in AuthorizeRequest event handler so that UrlAuthorizationModule module should only refer to original requested URL rather than rewritten URL.
  • Windows Authentication: In this case path should be rewritten in BeginRequest or AuthenticateRequest.

Sample 1: URL Rewriting using HTTP Module
publicclassURLRewriter : IHttpModule
{
#regionIHttpModule Members

publicvoid Dispose()
{

}

publicvoid Init(HttpApplication context)
{
context.BeginRequest += newEventHandler(context_BeginRequest);
}

void context_BeginRequest(object sender, EventArgs e)
{
HttpApplication application = sender as HttpApplication;

if (application != null)
{
if (application.Context.Request.Url.AbsolutePath.ToLower().Contains("/employee/"))
{
string employeeName = application.Context.Request.Url.Segments[application.Context.Request.Url.Segments.Length-1].Replace(".aspx","");

 

application.Context.RewritePath("~/EmployeeDatails.aspx?name=" + employeeName);
}
}
}

#endregion
}

In above example we are using BeginRequest event handler where we are checking outexpected URL and then rewriting it to the actual path if matches.
This custom Http Modules can be registered in configuration file of application as shown below

Registering custom Http Module in web.config of application
<httpModules>
<addname="URLWriter"type="HttpMdl.URLRewriter"/>

</httpModules>

2. HTTP Handler

ASP.Net offers URL rewriting using Http Handler or Http Handler Factory. As discussed Http Handler returns the response of the content to render at end user. Whereas Http Handler Factory returns the appropriate handler depending on the type of file being requested.

Custom Http handler factory can be imeplemated using IHttpHandlerFactorywhich needs to override the method GetHandler() that returns the instance of the handler of type IHttpHandler. As long as file type remains same we don’t need to implement custom HttpHandler. ASP.Net provides the default PageParserPage parser for .aspx files which includes the method GetCompiledPageInstancethat returns the compiled page from given virtual path.

Following code snippet illustrates the implementation of Http handler factory for URL rewriting.

URL Rewriting using HTTP Handler Factory
publicclassURLRewriter : IHttpHandlerFactory
{

publicIHttpHandler GetHandler(HttpContext context, string requestType, string url, string pathTranslated)
{
if (context.Request.Url.AbsolutePath.ToLower().Contains("/employee/"))
{
string employeeName = context.Request.Url.Segments[context.Request.Url.Segments.Length - 1].Replace(".aspx", "");

context.RewritePath("~/EmployeeDatails.aspx",string.Empty, "name=" + employeeName );

returnPageParser.GetCompiledPageInstance("~/EmployeeDatails.aspx", context.Server.MapPath("~/EmployeeDatails.aspx"), context);
}

returnPageParser.GetCompiledPageInstance(url, pathTranslated, context);
}

 

publicvoid ReleaseHandler(IHttpHandler handler)
{

}
}

In above example we are return default Http Handler after rewriting Url path to actual location.
This custom Http handler Factory can be registered in configuration file of application as shown below

Registering custom Http handler factory in web.config of application
<httpHandlers>
<addverb="*"path="*.aspx"validate="false"type="HttpHdl.URLRewriter"/>
</httpHandlers>

References
1. http://msdn.microsoft.com/en-us/library/ms972974.aspx
2. http://download.microsoft.com/download/0/4/6/0463611e-a3f9-490d-a08c-877a83b797cf/MSDNURLRewriting.msi
3. http://www.theserverside.net/tt/articles/showarticle.tss?id=IIS_ASP

Advertisements