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");
}
}
}
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.
ReplyDeleteThanks Matthew. Comments like yours are very important and one of purpose of this blog is to find always best solution for a problem.
Delete