Skip to content

Instantly share code, notes, and snippets.

@hendrasyp
Created November 8, 2019 03:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hendrasyp/67dbd0bcf8fd718f9dcf6892897ab568 to your computer and use it in GitHub Desktop.
Save hendrasyp/67dbd0bcf8fd718f9dcf6892897ab568 to your computer and use it in GitHub Desktop.
FilterIPAttribute for ASP.NET Web API (ported from https://gist.github.com/rdingwall/2028849), (IIS only, port of MVC version from http://stackoverflow.com/a/4605086/91551),
using Misc.Helpers.IPNumbers;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Web;
using System.Web.Http;
using System.Web.Http.Controllers;
namespace Misc.WebApi.Filters
{
#region IPFilter DDL
//CREATE TABLE[dbo].[GENERAL_PARAMETER]
//(
// [ID] int NOT NULL IDENTITY(1,1) ,
// [TEXT] varchar(MAX) COLLATE Latin1_General_CI_AS NULL ,
// [TYPE] varchar(150) COLLATE Latin1_General_CI_AS NULL ,
// [VALUE] varchar(MAX) COLLATE Latin1_General_CI_AS NULL ,
// [EDITABLE] bit NULL DEFAULT((0)) ,
// CONSTRAINT[PK_GENERAL_PARAMETER] PRIMARY KEY([ID])
//)
//ON[PRIMARY]
//TEXTIMAGE_ON[PRIMARY]
//GO
//INSERT INTO [dbo].[GENERAL_PARAMETER] ([TYPE], [VALUE], [EDITABLE]) VALUES('ALLOWED_SINGLE_IPs', '::1;127.0.0.1,36.69.138.73', '1');
//INSERT INTO [dbo].[GENERAL_PARAMETER] ([TYPE], [VALUE], [EDITABLE]) VALUES('ALLOWED_MASKED_IPs', '10.2.0.0;255.255.0.0,192.168.0.0;255.255.255.0', '1');
//INSERT INTO [dbo].[GENERAL_PARAMETER] ([TYPE], [VALUE], [EDITABLE]) VALUES('DENIED_SINGLE_IPs', NULL, '1');
//INSERT INTO [dbo].[GENERAL_PARAMETER] ([TYPE], [VALUE], [EDITABLE]) VALUES('DENIED_MASKED_IPs', NULL, '1');
#endregion
/// <summary>
/// Filter by IP address (ASP.NET Web API version)
/// Originally from http://stackoverflow.com/a/4605086/91551
/// ASP.NET Web API Version: https://gist.github.com/rdingwall/2028849
/// </summary>
public class FilterIPAttribute : AuthorizeAttribute
{
#region Allowed
/// <summary>
/// Comma seperated string of allowable IPs. Example "10.2.5.41,192.168.0.22"
/// </summary>
/// <value></value>
public string AllowedSingleIPs { get; set; }
/// <summary>
/// Comma seperated string of allowable IPs with masks. Example "10.2.0.0;255.255.0.0,10.3.0.0;255.255.0.0"
/// </summary>
/// <value>The masked I ps.</value>
public string AllowedMaskedIPs { get; set; }
/// <summary>
/// Gets or sets the configuration key for allowed single IPs
/// </summary>
/// <value>The configuration key single I ps.</value>
public string ConfigurationKeyAllowedSingleIPs { get; set; }
/// <summary>
/// Gets or sets the configuration key allowed mmasked IPs
/// </summary>
/// <value>The configuration key masked I ps.</value>
public string ConfigurationKeyAllowedMaskedIPs { get; set; }
/// <summary>
/// List of allowed IPs
/// </summary>
IPList allowedIPListToCheck = new IPList();
#endregion
#region Denied
/// <summary>
/// Comma seperated string of denied IPs. Example "10.2.5.41,192.168.0.22"
/// </summary>
/// <value></value>
public string DeniedSingleIPs { get; set; }
/// <summary>
/// Comma seperated string of denied IPs with masks. Example "10.2.0.0;255.255.0.0,10.3.0.0;255.255.0.0"
/// </summary>
/// <value>The masked I ps.</value>
public string DeniedMaskedIPs { get; set; }
/// <summary>
/// Gets or sets the configuration key for denied single IPs
/// </summary>
/// <value>The configuration key single I ps.</value>
public string ConfigurationKeyDeniedSingleIPs { get; set; }
/// <summary>
/// Gets or sets the configuration key for denied masked IPs
/// </summary>
/// <value>The configuration key masked I ps.</value>
public string ConfigurationKeyDeniedMaskedIPs { get; set; }
/// <summary>
/// List of denied IPs
/// </summary>
IPList deniedIPListToCheck = new IPList();
#endregion
/// <summary>
/// Determines whether access to the core framework is authorized.
/// </summary>
/// <param name="actionContext">The HTTP context, which encapsulates all HTTP-specific information about an individual HTTP request.</param>
/// <returns>
/// true if access is authorized; otherwise, false.
/// </returns>
/// <exception cref="T:System.ArgumentNullException">The <paramref name="httpContext"/> parameter is null.</exception>
protected override bool IsAuthorized(HttpActionContext actionContext)
{
if (actionContext == null)
throw new ArgumentNullException("actionContext");
string userIpAddress = ((HttpContextWrapper)actionContext.Request.Properties["MS_HttpContext"]).Request.UserHostName;
try
{
// Check that the IP is allowed to access
bool ipAllowed = CheckAllowedIPs(userIpAddress);
// Check that the IP is not denied to access
bool ipDenied = CheckDeniedIPs(userIpAddress);
// Only allowed if allowed and not denied
bool finallyAllowed = ipAllowed && !ipDenied;
return finallyAllowed;
}
catch (Exception e)
{
// Log the exception, probably something wrong with the configuration
}
return true; // if there was an exception, then we return true
}
private bool AuthorizeCore(HttpContextBase httpContext)
{
if (httpContext == null)
throw new ArgumentNullException("httpContext");
string userIpAddress = httpContext.Request.UserHostAddress;
try
{
// Check that the IP is allowed to access
bool ipAllowed = CheckAllowedIPs(userIpAddress);
// Check that the IP is not denied to access
bool ipDenied = CheckDeniedIPs(userIpAddress);
// Only allowed if allowed and not denied
bool finallyAllowed = ipAllowed && !ipDenied;
return finallyAllowed;
}
catch (Exception e)
{
// Log the exception, probably something wrong with the configuration
}
return true; // if there was an exception, then we return true
}
/// <summary>
/// Checks the allowed IPs.
/// </summary>
/// <param name="userIpAddress">The user ip address.</param>
/// <returns></returns>
private bool CheckAllowedIPs(string userIpAddress)
{
// Database logic or entities
BusinessLogic.GeneralParameter generalParameter = new BusinessLogic.GeneralParameter();
// Populate the IPList with the Single IPs
if (!string.IsNullOrEmpty(AllowedSingleIPs))
{
SplitAndAddSingleIPs(AllowedSingleIPs, allowedIPListToCheck);
}
// Populate the IPList with the Masked IPs
if (!string.IsNullOrEmpty(AllowedMaskedIPs))
{
SplitAndAddMaskedIPs(AllowedMaskedIPs, allowedIPListToCheck);
}
#region Allowed Single IP Address
// Check if there are more settings from the configuration (Web.config) or Database
if (!string.IsNullOrEmpty(ConfigurationKeyAllowedSingleIPs))
{
string configurationAllowedAdminSingleIPs = String.Empty;
string AllowSingleIPs = String.Empty;
AllowSingleIPs = (ConfigurationKeyAllowedSingleIPs == "FromDatabase") ?
generalParameter.GetSingleGeneralParamByType("ALLOWED_SINGLE_IPs").VALUE :
ConfigurationManager.AppSettings[ConfigurationKeyAllowedSingleIPs];
configurationAllowedAdminSingleIPs = AllowSingleIPs;
if (!string.IsNullOrEmpty(configurationAllowedAdminSingleIPs))
{
SplitAndAddSingleIPs(configurationAllowedAdminSingleIPs, allowedIPListToCheck);
}
}
#endregion
#region Allowed Masked IP Address
if (!string.IsNullOrEmpty(ConfigurationKeyAllowedMaskedIPs))
{
string configurationAllowedAdminMaskedIPs = String.Empty;
string AllowMaskedIPs = String.Empty;
AllowMaskedIPs = (ConfigurationKeyAllowedMaskedIPs == "FromDatabase") ?
generalParameter.GetSingleGeneralParamByType("ALLOWED_MASKED_IPs").VALUE :
ConfigurationManager.AppSettings[ConfigurationKeyAllowedMaskedIPs];
configurationAllowedAdminMaskedIPs = AllowMaskedIPs;
if (!string.IsNullOrEmpty(configurationAllowedAdminMaskedIPs))
{
SplitAndAddMaskedIPs(configurationAllowedAdminMaskedIPs, allowedIPListToCheck);
}
}
#endregion
return allowedIPListToCheck.CheckNumber(userIpAddress);
}
/// <summary>
/// Checks the denied IPs.
/// </summary>
/// <param name="userIpAddress">The user ip address.</param>
/// <returns></returns>
private bool CheckDeniedIPs(string userIpAddress)
{
// Database logic or entities
BusinessLogic.GeneralParameter generalParameter = new BusinessLogic.GeneralParameter();
// Populate the IPList with the Single IPs
if (!string.IsNullOrEmpty(DeniedSingleIPs))
{
SplitAndAddSingleIPs(DeniedSingleIPs, deniedIPListToCheck);
}
// Populate the IPList with the Masked IPs
if (!string.IsNullOrEmpty(DeniedMaskedIPs))
{
SplitAndAddMaskedIPs(DeniedMaskedIPs, deniedIPListToCheck);
}
#region Deny Single IPs
// Check if there are more settings from the configuration (Web.config)
if (!string.IsNullOrEmpty(ConfigurationKeyDeniedSingleIPs))
{
string configurationDeniedAdminSingleIPs = String.Empty;
string DenySingleIPs = String.Empty;
DenySingleIPs = (ConfigurationKeyDeniedSingleIPs == "FromDatabase") ?
generalParameter.GetSingleGeneralParamByType("DENIED_SINGLE_IPs").VALUE :
ConfigurationManager.AppSettings[ConfigurationKeyDeniedSingleIPs];
configurationDeniedAdminSingleIPs = DenySingleIPs;
if (!string.IsNullOrEmpty(configurationDeniedAdminSingleIPs))
{
SplitAndAddSingleIPs(configurationDeniedAdminSingleIPs, deniedIPListToCheck);
}
}
#endregion
#region Deny Masked IPs
if (!string.IsNullOrEmpty(ConfigurationKeyDeniedMaskedIPs))
{
string configurationDeniedAdminMaskedIPs = String.Empty;
string DenyMaskedIPs = String.Empty;
DenyMaskedIPs = (ConfigurationKeyDeniedMaskedIPs == "FromDatabase") ?
generalParameter.GetSingleGeneralParamByType("DENIED_MASKED_IPs").VALUE :
ConfigurationManager.AppSettings[ConfigurationKeyDeniedMaskedIPs];
configurationDeniedAdminMaskedIPs = DenyMaskedIPs;
if (!string.IsNullOrEmpty(configurationDeniedAdminMaskedIPs))
{
SplitAndAddMaskedIPs(configurationDeniedAdminMaskedIPs, deniedIPListToCheck);
}
}
#endregion
return deniedIPListToCheck.CheckNumber(userIpAddress);
}
/// <summary>
/// Splits the incoming ip string of the format "IP,IP" example "10.2.0.0,10.3.0.0" and adds the result to the IPList
/// </summary>
/// <param name="ips">The ips.</param>
/// <param name="list">The list.</param>
private void SplitAndAddSingleIPs(string ips, IPList list)
{
var splitSingleIPs = ips.Split(',');
foreach (string ip in splitSingleIPs)
list.Add(ip);
}
/// <summary>
/// Splits the incoming ip string of the format "IP;MASK,IP;MASK" example "10.2.0.0;255.255.0.0,10.3.0.0;255.255.0.0" and adds the result to the IPList
/// </summary>
/// <param name="ips">The ips.</param>
/// <param name="list">The list.</param>
private void SplitAndAddMaskedIPs(string ips, IPList list)
{
var splitMaskedIPs = ips.Split(',');
foreach (string maskedIp in splitMaskedIPs)
{
var ipAndMask = maskedIp.Split(';');
list.Add(ipAndMask[0], ipAndMask[1]); // IP;MASK
}
}
/// <summary>
/// Authorization for ASP.NET Web API
/// originally taken from https://gist.github.com/rdingwall/2028849
/// </summary>
/// <param name="actionContext"></param>
public override void OnAuthorization(HttpActionContext actionContext)
{
if (AuthorizeCore((HttpContextBase)actionContext.Request.Properties["MS_HttpContext"]))
return;
base.HandleUnauthorizedRequest(actionContext);
}
/// <summary>
/// MVC Version
/// </summary>
/// <param name="filterContext"></param>
// public override void OnAuthorization(AuthorizationContext filterContext)
// {
// base.OnAuthorization(filterContext);
// }
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment