LSTANCZYK
3/21/2017 - 5:01 PM

Ip address restriction action filter

Ip address restriction action filter

using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace Web.Attributes
{
    public class RestrictByIpAddressAttribute : ActionFilterAttribute
    {
        private IEnumerable<string> _allowedAddresses;

        public RestrictByIpAddressAttribute(string appSettingName)
        {
            GetConfig(appSettingName);
        }

        private void GetConfig(string appSettingName)
        {
            var addresses = (ConfigurationManager.AppSettings[appSettingName] ?? "")
                .Split(new string[] { " ", ";", ",", "\t" }, StringSplitOptions.RemoveEmptyEntries);

            _allowedAddresses = new List<string>(addresses);
        }

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

            var clientIpAddress = GetIpAddress();
            if (String.IsNullOrWhiteSpace(clientIpAddress) || (!_allowedAddresses.Contains(clientIpAddress)))
                filterContext.Result = new ContentResult() { Content = "ACCESS DENIED" };
        }

        /// <summary>
        /// Returns the current visitor's IP address. This method is more reliable than UserHostAddress because
        /// it works in conjunction with a load balancer, whereas UserHostAddress won't.
        /// </summary>
        /// <returns></returns>
        public static string GetIpAddress()
        {
            if (HttpContext.Current == null || HttpContext.Current.Request == null)
                return null;

            // this code gets the IP address. Cannot use "UserHostAddress" here
            // because the load balancer changes the IP address
            string ipAddress = (HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"] ?? "").Trim();
            if (!String.IsNullOrWhiteSpace(ipAddress))
            {
                // see this: http://www.jamescrowley.co.uk/2007/06/19/gotcha-http-x-forwarded-for-returns-multiple-ip-addresses/
                // can sometimes include multiple addresses (CSV) in the case of complicated load balancing rules
                // so pick out the last one
                if (ipAddress.Contains(","))
                    ipAddress = ipAddress.Split(',').Last();
            }

            // fall back to REMOTE_ADDR server variable
            if (String.IsNullOrWhiteSpace(ipAddress))
                ipAddress = HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];

            // ultimately fall back to UserHostAddress
            if (String.IsNullOrWhiteSpace(ipAddress))
                ipAddress = HttpContext.Current.Request.UserHostAddress;

            return ipAddress;
        }
    }
}