Impostare le regole di autorizzazione in un'area di ASP.NET MVC
Come sappiamo, sin da ASP.NET MVC 2 è possibile definire in un progetto delle particolari sezioni, denominate Area, che tipicamente risultano molto utili per separare le varie aree (per l'appunto) funzionali della nostra applicazione: se ad esempio abbiamo realizzato un sito web che prevede una parte pubblica e un backoffice di amministrazione, realizzare un'area di backoffice ci consente di specificare regole distinte per il routing e di differenziare i vari controller, model e view.
Purtroppo, ciò che ASP.NET MVC non fornisce è un sistema out-of-the-box per gestire le regole di autorizzazione di un'intera area. La soluzione più banale consiste nel derivare tutti i controller di una stessa area da una classe comune e applicare a quest'ultima il filtro AuthorizeAttribute:
[Authorize(Roles = "Administrators")] public class BackOfficeController : Controller { // classe base per i controller dell'area di backoffice } public class MailingListController : BackOfficeController { // controller per la gestione delle mailing list da backoffice }
Un'alternativa più strutturata, è invece quella di sfruttare una delle molteplici possibilità di customizzazione di ASP.NET MVC e, nella fattispecie, creare un AreaAuthorizationFilter che erediti da AuthorizeAttribute e supporti questa funzionalità:
public class AreaAuthorizationFilter : AuthorizeAttribute { public string AreaName { get; set; } public AreaAuthorizationFilter(string areaName) { this.AreaName = areaName ?? string.Empty; } public override void OnAuthorization(AuthorizationContext filterContext) { string requestAreaName = filterContext.RouteData.DataTokens["area"] as string ?? string.Empty; if (this.AreaName == requestAreaName) { base.OnAuthorization(filterContext); } } }
La logica di funzionamento è davvero semplice e, in buona sostanza, si limita a recuperare il nome dell'area dai dati routing e a confrontarla con quella per cui sono state fornite le specifiche di autorizzazione: solo nel caso in cui queste corrispondano, verrà invocata l'implementazione standard di OnAuthorization, che provvederà a sollevare una SecurityException se l'utente non possiede i permessi necessari. In tutti gli altri casi, invece, la gestione della security verrà totalmente bypassata.
Il vantaggio di questa tipologia di filtro è che può essere registrato tra i global filter in global.asax; pertanto è una soluzione estremamente più pratica rispetto alla prima proposta:
public void Application_Start() { GlobalFilters.Filters.Add( new AreaAuthorizationFilter("Backoffice") { Roles = "Administrators" }); }







