Adding IP restriction to a web page in ASP.NET

In some cases , you may want to restrict access to a certain aspx page based on a restricted IP list. For instance, you way want admin reports to be accessed only from the head office or you may want a particular page to be accessible only from a certain location(s).

This can be easily handled at the page level . The concept involves two things:

  1. Setup a file of valid IP ranges
  2. Query the file to check against the client IP to allow or disallow access

The IP list file

This is a simple ASCII text file in the format: start ip range-ending ip range

An example list would be

10.255.128.20-10.255.128.36
10.255.129.11-10.255.129.30
10.255.130.11-10.255.130.22
10.255.131.4-10.255.131.10
10.255.132.1-10.255.132.10
10.255.132.7-10.255.132.7

This file can be edited manually offline since its unlikely that it will be edited very often,

THE IP CHECKING CODE

We define a class which will take in an IP address range and then validate a given IP against it. The calling code will open the ip list file and run the class against each of the ip ranges in the file. If it finds a match in any ip range, it will allow access to the page:

The code for the class is given below:

public class IPAddressRange
{
    private AddressFamily addressFamily;
    private byte[] lowerBytes;
    private byte[] upperBytes;

    public IPAddressRange(IPAddress lower, IPAddress upper)
    {
        // Assert that lower.AddressFamily == upper.AddressFamily
        this.addressFamily = lower.AddressFamily;
        this.lowerBytes = lower.GetAddressBytes();
        this.upperBytes = upper.GetAddressBytes();
    }

    public bool IsInRange(IPAddress address)
    {
        if (address.AddressFamily != addressFamily)
        {
            return false;
        }

        byte[] addressBytes = address.GetAddressBytes();

        bool lowerBoundary = true, upperBoundary = true;

        for (int i = 0; i < this.lowerBytes.Length &&
            (lowerBoundary || upperBoundary); i++)
        {
            if ((lowerBoundary && addressBytes[i] < lowerBytes[i]) ||
                (upperBoundary && addressBytes[i] > upperBytes[i]))
            {
                return false;
            }

            lowerBoundary &= (addressBytes[i] == lowerBytes[i]);
            upperBoundary &= (addressBytes[i] == upperBytes[i]);
        }

        return true;
    }
}

The calling code is given below. Here its in the Page_Load event:

    protected void Page_Load(object sender, EventArgs e)
    {
                // check for valid ip
        if (!Page.IsPostBack)
        {
            bool allow = false;
            string clientIP = Request.UserHostAddress;
            string fileName = Server.MapPath("~") + "/validIPS.txt";
            StreamReader rdr = new StreamReader(fileName);
            string data = rdr.ReadToEnd();
            rdr.Close();

            data = data.Replace('\r', ' ');
            string[] lines = data.Split('\n');
            for (int i = 0; i < lines.Length; i++)
            {
                string[] range = lines[i].Split('-');
                string lower = range[0].Trim();
                string upper = range[1].Trim();
                IPAddress ipLower = IPAddress.Parse(lower);
                IPAddress ipUpper = IPAddress.Parse(upper);
                IPAddressRange ipRange = new IPAddressRange(ipLower, ipUpper);
                if (ipRange.IsInRange(IPAddress.Parse(clientIP)))
                    allow = true;
            }

         
            if (!allow)
            {
                Response.Write("You have been blocked due to IP restriction. Your IP is " + clientIP);
                Response.End();
            }
        }

Be sure to add
using System.IO;
using System.Net;
using System.Net.Sockets;

in the calling page

Be the first to comment

Leave a Reply

Your email address will not be published.


*


This site uses Akismet to reduce spam. Learn how your comment data is processed.