2

I'm using ASP.NET MVC 4 to build a simple intranet web app. I've put in place a login system and configure the RouteConfig.cs to display the login view as the "home page".

My question is simple : I've other views that "visitors" can't access if they're not logged. To perform tests, I try to access to these pages directly via the url and it works. How can I secure this by blocking the access to all the pages (excepted the login page)?

I've read things about the Web.config and authorizations but nothing worked. Any help guys?

EDIT : As Khanh TO told, working with the AutorizeAttribute is the best way to do it. However, I still have a little issue. When I'm logged as a simple user, I should not be able to see the admin pages (and that's the case) but when I attempt to do it, it redirects me to the login page (and I'm already logged !). I think this is because of the code below. The thing is, I would like to redirect to the home page if a user tries to attempt an unauthorized page. Possible to do that?

Here is the code I was speaking about :

<authentication mode="Forms">
      <forms loginUrl="~/User/Login" timeout="2880" />
</authentication>

Also, I wanted to precise that my users are stored into a simple table in which the role is defined by a bool type (isAdmin to know if a user is an admin or not).

Traffy
  • 2,803
  • 15
  • 52
  • 78

1 Answers1

10

If you need to selectively apply authorization for some pages, use AuthorizeAttribute on controller or action method:

Sample code:

 [Authorize]
 public class SecuredController : Controller
  {
       public ActionResult Index()
       {
            return View();
       }

  }

Or:

 public class SecuredController : Controller
   {
        [Authorize]
        public ActionResult Secure()
        {
            return View();
        }

        public ActionResult NonSecure()
        {
            return View();
        }
   }

Quoted from MSDN:

When you mark an action method with AuthorizeAttribute, access to that action method is restricted to users who are both authenticated and authorized. If you mark a controller with the attribute, all action methods in the controller are restricted.

The Authorize attribute lets you indicate that authorization is restricted to predefined roles or to individual users. This gives you a high degree of control over who is authorized to view any page on the site.

If an unauthorized user tries to access a method that is marked with the Authorize attribute, the MVC framework returns a 401 HTTP status code. If the site is configured to use ASP.NET forms authentication, the 401 status code causes the browser to redirect the user to the login page.

If you need to apply the authorize attribute globally except for the login page. You can add the AuthorizeAttribute to the global filter like this:

public static void RegisterGlobalFilters(GlobalFilterCollection filters)
  {
      filters.Add(new AuthorizeAttribute());
  }

And apply AllowAnonymousAttribute to your login view:

public class AccountController : Controller
    {
        [AllowAnonymous]
        public ActionResult Login()
        {
            return View();
        }
    }

In the web.config, enable Form Authentication:

<authentication mode="Forms">
      <forms loginUrl="~/Account/Login" timeout="2880" />
</authentication>
Khanh TO
  • 48,509
  • 13
  • 99
  • 115
  • Thank you for you help ! Could you please (or someone else) see my edited post? I still have a little question. – Traffy Mar 24 '14 at 08:52
  • @Traffy: firstly, using a boolean value is not a scalable solutions if we have more roles in the future. To do roles authorization in asp.net mvc, you could take a look at this discussion: http://stackoverflow.com/questions/1822548/mvc-how-to-store-assign-roles-of-authenticated-users – Khanh TO Mar 24 '14 at 12:49
  • @Traffy: if you need to redirect the user, using form authentication is the correct solution. Form authentication module intercepts 401 from AuthorizeAttribute and turns it into 302 to redirect the user as I quoted in the answer. – Khanh TO Mar 24 '14 at 12:55