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" }); }
Commenti
Per inserire un commento, devi avere un account.
Fai il login e torna a questa pagina, oppure registrati alla nostra community.
Approfondimenti
Utilizzare un numero per gestire la concorrenza ottimistica con SQL Server ed Entity Framework
Migliorare l'organizzazione delle risorse con Azure Policy
Generare velocemente pagine CRUD in Blazor con QuickGrid
Selettore CSS :has() e i suoi casi d'uso avanzati
Creare una libreria CSS universale: Nav menu
Garantire la provenienza e l'integrità degli artefatti prodotti su GitHub
Cancellare una run di un workflow di GitHub
Utilizzare QuickGrid di Blazor con Entity Framework
Utilizzare Copilot con Azure Cosmos DB
Eseguire operazioni sui blob con Azure Storage Actions
Utilizzare il metodo IntersectBy per eseguire l'intersection di due liste
Creare una libreria CSS universale: Cards