Click here to Skip to main content
15,887,364 members
Articles / Web Development / ASP.NET

Deployment-time Composability - Pre-processing and Post-processing Tasks during ASP.NET Web Page Request

Rate me:
Please Sign up or sign in to vote.
0.00/5 (No votes)
4 Aug 2011CPOL4 min read 12.1K  
Deployment-time composability - pre-processing and post-processing tasks during ASP.NET web page request

IHTTPModule

In web development, when you come across requirements that need to do some pre-processing and post-processing in a web page request; there are a couple of approaches to this; from the implementation stand point however why not do it in such a way that someone can disable/enable services without having to do code changes? Like from a config file.

Yes, I know Windows IIS supports ISAPI filters and ISAPI extensions but they can only be developed using C/C++; plus no other features from .NET Framework are supported (IIS6). Filters are registered at either the site level or the global level (apply to all sites on the IIS server). The product I work on, which is widely used by banks make use of ISAPI filters and they have been around a while, nevertheless there are other frameworks (frameworks that Intercepting Filter pattern) available which also support this functionality.

Ideally, you’d want to have the ability to add or remove modules at deployment time without having to make code changes as I mentioned before, this is often called “deployment composability”.

You can even add filters at deployment time by instantiating them dynamically based on a configuration file, and create a chain of composable filters. For this, the .NET Framework allows to add HttpModules, which kind of behaves like the global.asax normally would, in the sense that its methods can be used within the application context except modules need to be registered in the web.config before being used.

The idea here is that the filter can manipulate the context, for example, by adding information or redirecting the request. Benefit of this design is that filters are self-contained components without any direct dependency on the other filters or the controller.

Event-Driven Filters

The purpose of Intercepting Filter, on the other hand, is to intercept and modify the context in which it is called. Objects can "subscribe" to events without the original object being dependent on the observers. For example, an authentication filter may redirect the request to an error page or to the logon page if the authentication fails.

Filters that implement IHttpModule interface can be attached to a series of events defined by the framework. For example, some filters may expect certain processing to have occurred before they are invoked. Filters have no explicit mechanism for sharing state information with one another except to manipulate the context.

Implementation Details

The general process for writing a custom HTTP module in .NET is:

  • Implement the IHttpModule interface.
  • Handle the Init method and register for the events you need.
  • Handle the events.
  • Optionally, implement the Dispose method if you have to do cleanup.
  • Register the module in the web.config file.

I’ve put together a sample project which implements the following scenario: Let’s assume you work for a bank and you have been assigned a task to create a service (HttpModule) that basically identifies the user IP address every time they logged into the site and then compares it with the last 10.

IPs that correspond to the last 10 times the user logged on (obviously). With the purpose of identifying hack attempts made by malicious users from other geo-graphical locations. If that is the case, then you must redirect the user to another page which will prompt the user with a series of questions and for each question, the user must provide a valid answer so they can proceed, otherwise deny access.

I’ll start by creating the project solution named HttpModuleSampleSite, as such:

On the project, add App_Code folder from the Add ASP.NET folder options. On that folder, add a new class, name it something like:

IPAuthenticationServiceModule.cs

Once you added the class, go ahead and make it inherit from IHttpModule and implement its respective methods.

Now we can work implementing the handler, before we get into that, let me point out that you should be careful when working with HTTPModules not to fall into loops, furthermore, you really need to be aware of the event of the pipeline you are subscribing to as there is a chance some features won’t be available; for example the session state won’t be available on the event named AuthorizedRequest.

Here’s a portion of the implementation of the module:

C#
public void Init(HttpApplication context)
  {
    _httpApp = context;
        context.PostAcquireRequestState += new EventHandler(context_PostAcquireRequestState);
  }

    void context_PostAcquireRequestState(object sender, EventArgs e)
    {
        // this is how it should be => IPAddress.Parse(this._httpApp.Context.Request.UserHostAddress);
        // but for demo purpose we pretend the request is coming off somewhere else 

        if (_httpApp.Context.User.Identity.IsAuthenticated) 
        {            
        // Once the user has submitted all answers correctly this field 
        // should be available through session state life. 
            // We must check here because remember we're within a pipeline of subscribed events 
            if (_httpApp.Context.Session["doubts"] != 
                null && _httpApp.Context.Session["doubts"].ToString().Equals(
                "no doubts user validated")) 
            {               
             return; 
            }            
            // This portion of code will run only when the user 
            // has not submitted the answers correctly. 
            // (Evil user). 
            IPAddress ipaddress = IPAddress.Parse("209.191.122.70"); 
            bool match = _previusAddresses.Count 
                (
                    a => a.Equals(ipaddress)) == 10;
            //Be careful falling into loops 
            if (!match && !_httpApp.Context.Request.FilePath.Contains(
                "LogonQuestions.aspx")) 
            {
                _httpApp.Context.Response.Redirect(
                string.Format("~/LogonQuestions.aspx") 
                    );
            }
    }
}

You should find the project file zip down at the bottom of this page. Make sure to register the handler on the web.config file as follows:

Run the project and when the site loads, go ahead and click on register user and create a fake user.

Then click on Home button on the site and after that, on the upper right corner click on Login, use your fake user. After you are logged in, the fake IP should take place and you should get prompted with questions to validate user.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
-- There are no messages in this forum --