There are times during many site's life that you must perform some maintainence on the database / code, and allowing people to have access to the site whilst doing this must be restricted. Often most updates / upgrades can occur on the fly without any down time but there are occasions when you need to do this.
Usually I logon to my web server and IP Restrict the site to my IP Address and let IIS provide a default message to users that try to access the site during this period. Now although this works I often find it cumbersom, I have to have access to the web server, I need to find out my IP address, as I don't have a static one at home, and the entire process can be quite long. It's even worse if its for a site that I don't host and can't IP Restrict through IIS.
Another Way
Tonight I decided to explore a better way of doing this, and as such I've came up with a simple HTTPModule that you can stick into your ASP.Net Web Application which will handle IP Restrictions for you.
In order to maximise the use / potential of this module I've enabled it to do two things, first to allow conigurable IP Restrictions but secondly to specify whether the restriction is for a temporary basis, I.E the sites under maintainence, or whether this is a perminant block.
The Code
The code for this module is actually pretty simple. First of I created a class called IPRestrict and implemented the basic IHttpModule interface
namespace mjjames.HttpModules
{
public class IPRestrict : IHttpModule
{
public void Init(HttpApplication context)
{
}
public void Dispose()
{
}
}
}
With the basic interface I added a event handler to the init method that on BeginRequest, when a request starts to be processed, call Application_BeginRequest. Application_BeginRequest takes the user's IP Address from the Request object and passes this to ValidIP. ValidIP by default returns that the IP is valid, the site isn't using IP Restriction, however if the site's web.config has an app setting called "IPRestrict" then the provided ip address is searched for in the app setting.
private bool ValidIP(string ipaddress)
{
bool bValidIP = true;
if(!String.IsNullOrEmpty(ConfigurationManager.AppSettings["IPRestrict"])){
bValidIP = ConfigurationManager.AppSettings["IPRestrict"].Contains(ipaddress);
}
return bValidIP;
}
The reason i decided to perform a contains function on the app setting for the ip address was so that I could ignore the IP Address delimiter within the app setting. This way whether you seperate valid IPs with a comma, a space, a comma space etc it doesn't matter, as long as the IP is within the app setting it is returned as valid
As far as the IP Check goes that's it, however in order to make the module more usable and user friendly Application_Request can use an additional two app settings from the Web.Config. "MaintainenceMode" is boolean setting which indicates the IP Restriction is in use due to maintainence, if the setting is not provided then the module assumes this is not the case by default. Maintainence Mode changes the HTTP Response Status Code for the request, by default IP Restriction means the end user recieves a 403 status code, forbidden, however whilst in Maintainence Mode a 503 status code is delivered to indicate the service / site is temporarily unavailable.
The second app setting used in Application_Request is "CustomIPRestrictMessage". This setting as the name implies is used to provide a custom IP restriction message to the user instead of te default.
The module is really simple to use, simply add the mjjames.HttpModules dll to your project as a reference and update your web.config to include the app settings. Along with the app setting the HttpModule needs adding to the HTTPModules section of the web.config, find an example of how to do this below
That's it hopefully you'll find the module easy to use. Currently it doesn't do IP Ranges as I didnt require this, I may look at adding this in the future.
Now whilst testing this I thought about how I could provide more than a custom message upon recieving the IP Restriction response, maybe a branded page dependant on the site it's used in. This is actually very easy and all you need to do is create a custom html page branded appropiately within your site and then change the CustomErrors section of your web.config.
Within here simply add a new error node, give it either the 503 or 403 status code dependant on whether you are using maintainence mode or not, and provide the html file to redirect to.
This makes the module for me at least very useful. If you want to give the module a go why not download the dll and let me know how you get on. If there's interest I'll also look at bundling a version with the full source.