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
Creare una libreria CSS universale - Rotazione degli elementi
Utilizzare Tailwind CSS all'interno di React: primi componenti
Gestione dei nomi con le regole @layer in CSS
Triggerare una pipeline su un altro repository di Azure DevOps
Utilizzare il metodo CountBy di LINQ per semplificare raggruppamenti e i conteggi
Generare velocemente pagine CRUD in Blazor con QuickGrid
Usare le collection expression per inizializzare una lista di oggetti in C#
Proteggere le risorse Azure con private link e private endpoints
Configurare il nome della run di un workflow di GitHub in base al contesto di esecuzione
Recuperare App Service cancellati su Azure
Utilizzare un numero per gestire la concorrenza ottimistica con SQL Server ed Entity Framework
Sfruttare al massimo i topic space di Event Grid MQTT