views:

305

answers:

3

I've an Admin area and I want only Admins to enter the area. I considered adding the Authorized attribute to every controller in the Admin area. Isn't there an elegant solution or is this feature not there in the framework itself?

EDIT: I'm sorry, I should to have mentioned this before. I'm using a custom AuthorizedAttribute derived from AuthorizeAttribute.

A: 

Hi,

.. very crudely I believe you want something like this?

Quick and dirty role management

[Authorize(Roles = "Admins")]
public ActionResult Register()
{
  ViewData["roleName"] = new SelectList(Roles.GetAllRoles(), "roleName");
  ViewData["PasswordLength"] = MembershipService.MinPasswordLength;
  return View();
}
Ric Tokyo
+1  A: 

If all of your admin code is in one controller then add Authorize to the entire class.

[Authorize]
public class AdminController : Controller
{
     .......
}
John
+8  A: 

Web.config-based security should almost never be used in an MVC application. The reason for this is that multiple URLs can potentially hit a controller, and putting these checks in Web.config invariably misses something. Remember - controllers are not associated with areas, routes are associated with areas. The MVC controller factory will happily serve controllers from the Areas/ folder for non-area requests if there's no conflict.

For example, using the default project structure, adding an Admin area with an AdminDefaultController, you can hit this controller via /Admin/AdminDefault/Index and /AdminDefault/Index.

The only supported solution is to put your attribute on a controller base class and to ensure that each controller within the area subclasses that base class.

Levi
Well, is the a good way to be sure a controller is hit only via a single URL ? By a correct planing of routes maybe ?
Cédric Rup
There's no way to ensure a controller is accessible only via a single URL. Routes are simply *a* mechanism for accessing controllers; they are not *the* mechanism. This is why any security attributes need to be applied directly to the controllers themselves, not to the routes (and by extension, the areas). For example, consider the introduction of MvcHandler.ashx in MVC 3. This would call into the MVC framework directly by bypassing *all* of Routing.
Levi
Ok... does it mean there's no correct answer to the question beside a correct use of security attributes ?
Cédric Rup
Correct. Always assume that every public method of every controller is web-callable by the world. Then it makes sense that [Authorize], [NonAction], and other attributes are the correct way to secure these resources.
Levi