Search code examples
asp.net-mvc-4asp.net-mvc-areasrazor-2

How to protect an entire MVC Area by IP/Role/User?


I know in MVC at the top of a controller you can use the [Authorize()] attribute to restrict access to that entire controller to certain authenticated users and/or roles, but not by IP, but this must be done on a per controller instance. Is there a way to restrict access to an entire MVC Area to an authenticated User/Role or by the request Source IP?


Solution

  • Create a Base Controller in your area:

    [AuthorizeArea(AllowIpAddresses = new [] {"1.1.1.1", "1.2.3.4"})]
    public class CustomAreaBaseController : Controller
    {
        public CustomAreaBaseController()
        {
            // possibly any other common code that you want to run for all controllers in this area
        }
    }
    

    Have all controllers in your area derive from base controller:

    public class HomeController : CustomAreaBaseController
    {
        // actions for this controller
    }
    

    Create custom Authorize Attribute:

    public class AuthorizeArea : AuthorizeAttribute
    {
        public string[] AllowIpAddresses { get; set; }
    
        protected override bool AuthorizeCore(HttpContextBase httpContext)
        {
            bool isValid = false;
    
            if (httpContext == null)
                throw new ArgumentNullException("httpContext");
    
            // get current ip address
            var ipAddress = httpContext.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
            if (string.IsNullOrEmpty(ipAddress))
                ipAddress = httpContext.Request.ServerVariables["remote_host"];
    
            if (AllowIpAddresses.Contains(ipAddress)) isValid = true;
    
            return base.AuthorizeCore(httpContext) && isValid;
        }
    }