Using Action Filter Attribute to allow access only for specified IP addresses in ASP.NET MVC using C#



We want to be able to run action in mvc application only when authorized IP access the controller action. For instance we want to run some specific report but the report can only be run from sever or other authorized IP.

Create new class in your mvc application and call it ServerOnly.
We are going to store authorized list of IPs in WebConfig file.

Under appSetting in Webconfig file add this line :

<add key="Servers" value="::1,127.0.0.1";

::1 is the same as 127.0.0.1 in IPv6 and localhost. Simply saying the request has been generated on the server. You can easily add your ip to the list.

If access is granted action will be executed as normal, if not txt file UnauthorizedAccess will be created with ip address, user also will be redirect to UnauthorizedAccess action – this action has to be created in Account controller if you are using this code, but you can easily change routing, for instance:

filterContext.Result = new RedirectResult("~/MyController/UnathorizedAccess");


public class ServerOnly : ActionFilterAttribute

    {

        public override void OnActionExecuting(ActionExecutingContext filterContext)

        {

            var originatingAddress = filterContext.HttpContext.Request.UserHostAddress;

            var fileName = AppDomain.CurrentDomain.BaseDirectory + "App_Data\\" + "logs\\" + "ReportAccessed" + ".txt";

            string message = "Access : IP " + originatingAddress;

            var sw = new System.IO.StreamWriter(fileName, true);

            sw.WriteLine(message);

            sw.Close();

            var ips = System.Configuration.ConfigurationManager.AppSettings["Servers"]

                .Split(',')

                .Select(ip => ip.Trim())

                .ToList();

             if(ips.Contains(originatingAddress))
             {

                 base.OnActionExecuting(filterContext);

             }

             else

             {

                 // Record ip of unathorized access

                 var loginNow = DateTime.Now;

                 var splitDate = loginNow.ToString().Replace('/', '_').ToString().Replace(' ', '_').ToString().Replace(':', '-').ToString();

                 fileName = AppDomain.CurrentDomain.BaseDirectory + "App_Data\\" + "logs\\" + "UnauthorizedAccess + splitDate" + ".txt";

                 message = "Unathorized access : IP " + originatingAddress;

                 sw = new System.IO.StreamWriter(fileName, true);

                 sw.WriteLine(message);

                 sw.Close();

                 filterContext.Result = new RedirectResult("~/Account/UnathorizedAccess");

             }

        }

    }


Comments

  1. I recommend taking your ips and putting in a static variable, since this won't change without a refresh of the appdomain anyway. Reading that value, splitting it and all that each time you run an action will add up over time and slow down your app. Also, writing down to your file system each time will also kill performance, so use a dedicated logging system like NLog or log4net and it'll give you some added flexibility.

    ReplyDelete
    Replies
    1. Thanks Matthew. Comments like yours are very important and one of purpose of this blog is to find always best solution for a problem.

      Delete

Post a Comment