Skip to content

Instantly share code, notes, and snippets.

@ntotten
Last active October 27, 2019 16:13
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save ntotten/6539951 to your computer and use it in GitHub Desktop.
Save ntotten/6539951 to your computer and use it in GitHub Desktop.
IP Address Filter for Windows Azure Web Sites
This software is released under the Apache License 2.0 (the "License");
you may not use the software except in compliance with the License. You
can find a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.html.
[IPFilter("192.168.0.0/24")]
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
//SOURCE: http://blogs.msdn.com/b/knom/archive/2008/12/31/ip-address-calculations-with-c-subnetmasks-networks.aspx
namespace Knom.Helpers.Net
{
public static class SubnetMask
{
public static readonly IPAddress ClassA = IPAddress.Parse("255.0.0.0");
public static readonly IPAddress ClassB = IPAddress.Parse("255.255.0.0");
public static readonly IPAddress ClassC = IPAddress.Parse("255.255.255.0");
public static IPAddress CreateByHostBitLength(int hostpartLength)
{
int hostPartLength = hostpartLength;
int netPartLength = 32 - hostPartLength;
if (netPartLength < 2)
throw new ArgumentException("Number of hosts is to large for IPv4");
Byte[] binaryMask = new byte[4];
for (int i = 0; i < 4; i++)
{
if (i * 8 + 8 <= netPartLength)
binaryMask[i] = (byte)255;
else if (i * 8 > netPartLength)
binaryMask[i] = (byte)0;
else
{
int oneLength = netPartLength - i * 8;
string binaryDigit =
String.Empty.PadLeft(oneLength, '1').PadRight(8, '0');
binaryMask[i] = Convert.ToByte(binaryDigit, 2);
}
}
return new IPAddress(binaryMask);
}
public static IPAddress CreateByNetBitLength(int netpartLength)
{
int hostPartLength = 32 - netpartLength;
return CreateByHostBitLength(hostPartLength);
}
public static IPAddress CreateByHostNumber(int numberOfHosts)
{
int maxNumber = numberOfHosts + 1;
string b = Convert.ToString(maxNumber, 2);
return CreateByHostBitLength(b.Length);
}
}
public static class IPAddressExtensions
{
public static IPAddress GetBroadcastAddress(this IPAddress address, IPAddress subnetMask)
{
byte[] ipAdressBytes = address.GetAddressBytes();
byte[] subnetMaskBytes = subnetMask.GetAddressBytes();
if (ipAdressBytes.Length != subnetMaskBytes.Length)
throw new ArgumentException("Lengths of IP address and subnet mask do not match.");
byte[] broadcastAddress = new byte[ipAdressBytes.Length];
for (int i = 0; i < broadcastAddress.Length; i++)
{
broadcastAddress[i] = (byte)(ipAdressBytes[i] | (subnetMaskBytes[i] ^ 255));
}
return new IPAddress(broadcastAddress);
}
public static IPAddress GetNetworkAddress(this IPAddress address, IPAddress subnetMask)
{
byte[] ipAdressBytes = address.GetAddressBytes();
byte[] subnetMaskBytes = subnetMask.GetAddressBytes();
if (ipAdressBytes.Length != subnetMaskBytes.Length)
throw new ArgumentException("Lengths of IP address and subnet mask do not match.");
byte[] broadcastAddress = new byte[ipAdressBytes.Length];
for (int i = 0; i < broadcastAddress.Length; i++)
{
broadcastAddress[i] = (byte)(ipAdressBytes[i] & (subnetMaskBytes[i]));
}
return new IPAddress(broadcastAddress);
}
public static bool IsInSameSubnet(this IPAddress address2, IPAddress address, IPAddress subnetMask)
{
IPAddress network1 = address.GetNetworkAddress(subnetMask);
IPAddress network2 = address2.GetNetworkAddress(subnetMask);
return network1.Equals(network2);
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.Mvc;
using Knom.Helpers.Net;
namespace Sample.Filters
{
public class IPFilterAttribute : AuthorizeAttribute
{
public bool AllowLocalhost { get; set; }
public string AuthorizedIPAddress { get; set; }
public IPFilterAttribute(string authorizedIPAddress)
{
this.AllowLocalhost = true;
this.AuthorizedIPAddress = authorizedIPAddress;
}
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
var clientIP = httpContext.Request.Headers["X-Forwarded-For"];
var isAuthorized = IsAuthorizedIPAddress(this.AuthorizedIPAddress, clientIP);
return isAuthorized || (this.AllowLocalhost && (httpContext.Request.Url.Host == "localhost"));
}
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
filterContext.HttpContext.Response.StatusCode = 401;
filterContext.HttpContext.Response.End();
}
private static bool IsAuthorizedIPAddress(string authorizedIP, string clientIP)
{
if (!String.IsNullOrEmpty(clientIP))
{
if (clientIP.Contains(':'))
{
clientIP = clientIP.Split(':')[0];
}
IPAddress parsedClientIP;
if (IPAddress.TryParse(clientIP, out parsedClientIP))
{
var authorizedSubnet = SubnetMask.CreateByHostNumber(1);
if (authorizedIP.Contains('/'))
{
var ipParts = authorizedIP.Split('/');
authorizedIP = ipParts[0];
authorizedSubnet = SubnetMask.CreateByNetBitLength(int.Parse(ipParts[1]));
}
var parsedIP = IPAddress.Parse(authorizedIP);
return parsedClientIP.IsInSameSubnet(parsedIP, SubnetMask.ClassB);
}
}
return false;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment