Ограничить доступ к определенному контроллеру по IP-адресу в ASP.NET MVC Beta


У меня есть ASP.NET проект MVC, содержащий класс AdminController и дающий мне такие URL-адреса:

http://example.com/admin/AddCustomer

http://examle.com/Admin/ListCustomers

Я хочу настроить сервер / приложение так, чтобы URI, содержащие / Admin доступны только из сети 192.168.0.0/24 (т. е. в нашей локальной сети)

Я хотел бы ограничить этот контроллер были доступны только с определенных IP-адресов.

В разделе WebForms /admin / была физической папкой, которую я мог ограничить в IIS... но с MVC, конечно, нет физической папки. Это достижимо с помощью интернета.конфигурация или атрибуты, или мне нужно перехватить HTTP-запрос для достижения этого?

4 58

4 ответа:

Я знаю, что это старый вопрос, но мне нужно было иметь эту функциональность сегодня, поэтому я реализовал ее и подумал о ее публикации здесь.

используя класс IPList отсюда (http://www.codeproject.com/KB/IP/ipnumbers.aspx)

атрибут filter 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);
        }
    }
}

пример использования:

1. Прямое указание IP-адресов в код

    [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. Или загрузите конфигурацию из интернета.конфигурации

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

вы должны иметь доступ к UserHostAddress в объекте запроса в вашем контроллере, чтобы сделать ограничение. Я бы предположил, что вы можете расширить AuthorizeAttribute и добавить IP адрес его ограничений, так что вы можете просто украсить любые методы или контроллеры, которые нуждаются в такой защите.

Мне нужно было решение этой проблемы в MVC4, которое могло бы обрабатывать диапазоны IPv6 и IP. Кроме того, мне нужно было использовать белый и черный списки для авторизации, но также использовать обычный процесс авторизации, когда IP не был ни тем, ни другим.

Это решение, к которому я пришел, взяв много от @sabbour и @Richard Szalay(Как проверить входное падение IP в определенном диапазоне IP) потрясающие сообщения, поэтому я отправляю его сюда для тех, кому это может помочь.

public class MagniAuthorizeAttribute : FilterAttribute, IAuthorizationFilter
{

    #region Allowed

    public bool IsPublic { get; set; }
    /// <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 AllowedIPRanges { 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; }

    #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 DeniedIPRanges { 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; }

    #endregion


    /// <summary>
    /// Checks the allowed IPs.
    /// </summary>
    /// <param name="userIpAddress">The user ip address.</param>
    /// <returns></returns>
    private bool CheckAllowedIPs(IPAddress userIpAddress)
    {
        List<IPAddress> allowedIPsToCheck = new List<IPAddress>();
        List<IPAddressRange> allowedIPRangesToCheck = new List<IPAddressRange>();

        // Populate the IPList with the Single IPs
        if (!string.IsNullOrEmpty(AllowedSingleIPs))
        {
            SplitAndAddSingleIPs(AllowedSingleIPs, allowedIPsToCheck);
        }

        // Populate the IPList with the Masked IPs
        if (!string.IsNullOrEmpty(AllowedIPRanges))
        {
            SplitAndAddIPRanges(AllowedIPRanges, allowedIPRangesToCheck);
        }

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

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

        return allowedIPsToCheck.Any(a => a.Equals(userIpAddress)) || allowedIPRangesToCheck.Any(a => a.IsInRange(userIpAddress));
    }

    /// <summary>
    /// Checks the denied IPs.
    /// </summary>
    /// <param name="userIpAddress">The user ip address.</param>
    /// <returns></returns>
    private bool CheckDeniedIPs(IPAddress userIpAddress)
    {
        List<IPAddress> deniedIPsToCheck = new List<IPAddress>();
        List<IPAddressRange> deniedIPRangesToCheck = new List<IPAddressRange>();

        // Populate the IPList with the Single IPs
        if (!string.IsNullOrEmpty(DeniedSingleIPs))
        {
            SplitAndAddSingleIPs(DeniedSingleIPs, deniedIPsToCheck);
        }

        // Populate the IPList with the Masked IPs
        if (!string.IsNullOrEmpty(DeniedIPRanges))
        {
            SplitAndAddIPRanges(DeniedIPRanges, deniedIPRangesToCheck);
        }

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

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

        return deniedIPsToCheck.Any(a => a.Equals(userIpAddress)) || deniedIPRangesToCheck.Any(a => a.IsInRange(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 IPAddress list
    /// </summary>
    /// <param name="ips">The ips.</param>
    /// <param name="list">The list.</param>
    private void SplitAndAddSingleIPs(string ips, List<IPAddress> list)
    {
        var splitSingleIPs = ips.Split(',');
        IPAddress ip;

        foreach (string ipString in splitSingleIPs)
        {
            if(IPAddress.TryParse(ipString, out ip))
                list.Add(ip);
        }
    }

    /// <summary>
    /// Splits the incoming ip ranges string of the format "IP-IP,IP-IP" example "10.2.0.0-10.2.255.255,10.3.0.0-10.3.255.255" and adds the result to the IPAddressRange list
    /// </summary>
    /// <param name="ips">The ips.</param>
    /// <param name="list">The list.</param>
    private void SplitAndAddIPRanges(string ips, List<IPAddressRange> list)
    {
        var splitMaskedIPs = ips.Split(',');
        IPAddress lowerIp;
        IPAddress upperIp;
        foreach (string maskedIp in splitMaskedIPs)
        {
            var ipRange = maskedIp.Split('-');
            if (IPAddress.TryParse(ipRange[0], out lowerIp) && IPAddress.TryParse(ipRange[1], out upperIp))
                list.Add(new IPAddressRange(lowerIp, upperIp));
        }
    }

    protected void HandleUnauthorizedRequest(AuthorizationContext context)
    {
        context.Result = new RedirectToRouteResult(new RouteValueDictionary { { "Controller", "Home" },
                                                                                    { "Action", "Login" },
                                                                                    { "OriginalURL", context.HttpContext.Request.Url.AbsoluteUri } });
    }

    protected bool AuthorizeCore(AuthorizationContext context)
    {
        try
        {
            string userIPString = context.HttpContext.Request.UserHostName;
            IPAddress userIPAddress = IPAddress.Parse(userIPString);

            // Check that the IP is allowed to access
            bool? ipAllowed = CheckAllowedIPs(userIPAddress) ? true : (bool?)null;

            // Check that the IP is not denied to access
            ipAllowed = CheckDeniedIPs(userIPAddress) ? false : ipAllowed;

            if (ipAllowed.HasValue)
            {
                return ipAllowed.Value;
            }

            var serverSession = context.HttpContext.Session;

            UserSession session = null;

            //usersession in server session
            if (serverSession[Settings.HttpContextUserSession] != null)
            {
                session = (UserSession)serverSession[Settings.HttpContextUserSession];
                Trace.TraceInformation($"[{MethodBase.GetCurrentMethod().Name}] UserId:" + session.UserId + ". ClientId: " + session.ClientId);
                return true;
            }

            //usersession in database from cookie
            session = UserSession.GetSession(context.HttpContext.Request.Cookies.Get("sessionId").Value);
            if (session != null)
            {
                Trace.TraceInformation($"[{MethodBase.GetCurrentMethod().Name}] Session found for cookie {context.HttpContext.Request.Cookies.Get("sessionId").Value}");
                serverSession[Settings.HttpContextUserSession] = session;
                Trace.TraceInformation($"[{MethodBase.GetCurrentMethod().Name}] UserId:" + session.UserId + ". ClientId: " + session.ClientId);

                return true;
            }
            else
            {
                Trace.TraceInformation($"[{MethodBase.GetCurrentMethod().Name}] No session found for cookie {serverSession["cookie"]}");
                return false;
            }

        }
        catch (Exception ex)
        {
            Trace.TraceError($"[{MethodBase.GetCurrentMethod().Name}] exception: {ex.Message} - trace {ex.StackTrace}");
            return false;
        }
    }

    public void OnAuthorization(AuthorizationContext actionContext)
    {
        if (IsPublic == false && AuthorizeCore(actionContext) == false)
        {
            HandleUnauthorizedRequest(actionContext);
        }
    }
}

я нашел решение sabbour отличным, но мне нужно было внести два изменения, чтобы быть более полезным для моих целей:

  1. разрешить доступ, если разрешены список пуст. Таким образом, вы можете разрешить любой IP-адрес, просто изменив конфигурацию (например, для тестовых развертываний) или разрешить все IP-адреса, кроме явно запрещенных. Для этого я расширил IPList до включите свойство Count и проверьте его как часть CheckAllowedIPs:

    return _allowedIpListToCheck.Count == 0 || _allowedIpListToCheck.CheckNumber(userIpAddress);
    
  2. переопределить HandleUnauthorizedRequest всегда возвращает 403. AuthorizeAtrribute возвращает 401 по умолчанию:

    public override void OnAuthorization(AuthorizationContext actionContext)
    {
        if (AuthorizeCore((HttpContextBase)actionContext.HttpContext))
            return;
        HandleUnauthorizedRequest(actionContext);
    }
    
    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
            filterContext.Result = new HttpStatusCodeResult(403, "IP Access Denied");
    }
    

вот полная вариация класса FilterIpAttribute:

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>
    readonly 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>
    readonly IpList _deniedIpListToCheck = new IpList();
    #endregion

    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        if (httpContext == null)
            throw new ArgumentNullException("httpContext");

        string userIpAddress = httpContext.Request.UserIp();

        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.Count == 0 || _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 actionContext)
    {
        if (AuthorizeCore((HttpContextBase)actionContext.HttpContext))
            return;
        HandleUnauthorizedRequest(actionContext);
    }

    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
            filterContext.Result = new HttpStatusCodeResult(403, "IP Access Denied");
    }
}

метод расширения для получения IP-адреса пользователя, предложенный osa on github

public static class HttpUtils {

    public static string UserIp(this HttpRequestBase request)
    {
        var ip = request["HTTP_X_FORWARDED_FOR"];

        if (!string.IsNullOrWhiteSpace(ip))
        {
            ip = ip.Split(',').Last().Trim();
        }

        if (string.IsNullOrWhiteSpace(ip))
        {
            ip = request.UserHostAddress;
        }

        return ip;
    }
}

и, наконец, модификация IPList (полный источник здесь):

internal class IpArrayList
{
    //[...]
    public int Count
    {
        get { return _ipNumList.Count; }
    }

 }

public class IpList
{
      //[...]
     public int Count
     {
         get { return _usedList.Count; }
     }
}