Restrict Access to a Specific Controller by Ip Address in ASP.NET MVC Beta

Restrict access to a specific controller by IP address in ASP.NET MVC Beta

I know this is an old question, but I needed to have this functionality today so I implemented it and thought about posting it here.

Using the IPList class from here (http://www.codeproject.com/KB/IP/ipnumbers.aspx)

The filter attribute FilterIPAttribute.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Http;
using System.Security.Principal;
using System.Configuration;

namespace Miscellaneous.Attributes.Controller
{

/// <summary>
/// Filter by IP address
/// </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
}

/// <summary>
/// Checks the allowed IPs.
/// </summary>
/// <param name="userIpAddress">The user ip address.</param>
/// <returns></returns>
private bool CheckAllowedIPs(string userIpAddress)
{
// 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);
}

// Check if there are more settings from the configuration (Web.config)
if (!string.IsNullOrEmpty(ConfigurationKeyAllowedSingleIPs))
{
string configurationAllowedAdminSingleIPs = ConfigurationManager.AppSettings[ConfigurationKeyAllowedSingleIPs];
if (!string.IsNullOrEmpty(configurationAllowedAdminSingleIPs))
{
SplitAndAddSingleIPs(configurationAllowedAdminSingleIPs, allowedIPListToCheck);
}
}

if (!string.IsNullOrEmpty(ConfigurationKeyAllowedMaskedIPs))
{
string configurationAllowedAdminMaskedIPs = ConfigurationManager.AppSettings[ConfigurationKeyAllowedMaskedIPs];
if (!string.IsNullOrEmpty(configurationAllowedAdminMaskedIPs))
{
SplitAndAddMaskedIPs(configurationAllowedAdminMaskedIPs, allowedIPListToCheck);
}
}

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)
{
// 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);
}

// Check if there are more settings from the configuration (Web.config)
if (!string.IsNullOrEmpty(ConfigurationKeyDeniedSingleIPs))
{
string configurationDeniedAdminSingleIPs = ConfigurationManager.AppSettings[ConfigurationKeyDeniedSingleIPs];
if (!string.IsNullOrEmpty(configurationDeniedAdminSingleIPs))
{
SplitAndAddSingleIPs(configurationDeniedAdminSingleIPs, deniedIPListToCheck);
}
}

if (!string.IsNullOrEmpty(ConfigurationKeyDeniedMaskedIPs))
{
string configurationDeniedAdminMaskedIPs = ConfigurationManager.AppSettings[ConfigurationKeyDeniedMaskedIPs];
if (!string.IsNullOrEmpty(configurationDeniedAdminMaskedIPs))
{
SplitAndAddMaskedIPs(configurationDeniedAdminMaskedIPs, deniedIPListToCheck);
}
}

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
}
}

public override void OnAuthorization(AuthorizationContext filterContext)
{
base.OnAuthorization(filterContext);
}
}
}

Example usage:

1. Directly specifying the IPs in the
code

    [FilterIP(
AllowedSingleIPs="10.2.5.55,192.168.2.2",
AllowedMaskedIPs="10.2.0.0;255.255.0.0,192.168.2.0;255.255.255.0"
)]
public class HomeController {
// Some code here
}

2. Or, Loading the configuration from the Web.config

    [FilterIP(
ConfigurationKeyAllowedSingleIPs="AllowedAdminSingleIPs",
ConfigurationKeyAllowedMaskedIPs="AllowedAdminMaskedIPs",
ConfigurationKeyDeniedSingleIPs="DeniedAdminSingleIPs",
ConfigurationKeyDeniedMaskedIPs="DeniedAdminMaskedIPs"
)]
public class HomeController {
// Some code here
}

<configuration>
<appSettings>
<add key="AllowedAdminSingleIPs" value="localhost,127.0.0.1"/> <!-- Example "10.2.80.21,192.168.2.2" -->
<add key="AllowedAdminMaskedIPs" value="10.2.0.0;255.255.0.0"/> <!-- Example "10.2.0.0;255.255.0.0,192.168.2.0;255.255.255.0" -->
<add key="DeniedAdminSingleIPs" value=""/> <!-- Example "10.2.80.21,192.168.2.2" -->
<add key="DeniedAdminMaskedIPs" value=""/> <!-- Example "10.2.0.0;255.255.0.0,192.168.2.0;255.255.255.0" -->
</appSettings>
</configuration>

restrict access to mvc controller using ip address

If you have hosted your application locally (VS built-in web server) and accessing it locally chances are your IP is 127.0.0.1 as returned by httpContext.Request.UserHostAddress. Try debugging the code by placing breakpoints in order to see what's going on.

How to restrict access of controller action in ASP.net MVC 5

What you'd want to do is create a custom Action Filter, which would allow you to define custom logic within your action to determine if a given user could / could not access the decorated action:

public class SomeRuleAttribute : System.Web.Mvc.ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
base.OnActionExecuting(filterContext);

// Define some condition to check here
if (condition)
{
// Redirect the user accordingly
filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary { { "controller", "Account" }, { "action", "LogOn" } });
}
}
}

You can also extend these even further and set properties on them as well if you need to apply some values to check against where the attribute is defined:

public class SomeRule: ActionFilterAttribute
{
// Any public properties here can be set within the declaration of the filter
public string YourProperty { get; set; }

public override void OnActionExecuting(ActionExecutingContext filterContext)
{
base.OnActionExecuting(filterContext);

// Define some condition to check here
if (condition && YourProperty == "some value")
{
// Redirect the user accordingly
filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary { { "controller", "Account" }, { "action", "LogOn" } });
}
}
}

This would look like the following when used:

[SomeRule(YourProperty = "some value")]
public ActionResult YourControllerAction()
{
// Code omitted for brevity
}

How do I limit access to certain controllers to my own application in MVC3?

So it sounds like you are using an external postcode lookup service (where I assume you pay-per-request) and you don't want someone else to make postcode lookup requests by piggy-backing on your service, where you will get charged?

The first thing you should do is check whether your service provider allows you to specify a whitelist of referrers. Since many of these apis mean your "api key" is in javascript somewhere, this is often used to only allow service requests (using your key) from a specific host or ip address.

With this done, you'll want to ensure that your post code lookup action is only called from pages within your site.

You can do this with some kind of anti forgery token on the client. Phil Haack posted recently about getting this to work with AJAX posts.

IIS/ASP.NET MVC: Dynamic IP Address Restrictions on specific folder

Location elements can still be used in MVC to apply configuration (like IP restrictions) to certain parts of your MVC app:

<location path="secret/api">
<system.webServer>
<security>
<ipSecurity allowUnlisted="false">
<clear/>
<add ipAddress="127.0.0.1"/>
</ipSecurity>
</security>
</system.webServer>
</location>


Related Topics



Leave a reply



Submit