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
Generare HTML a runtime a partire da un componente Razor in ASP.NET Core
Triggerare una pipeline su un altro repository di Azure DevOps
Utilizzare EF.Constant per evitare la parametrizzazione di query SQL
Gestire la cancellazione di una richiesta in streaming da Blazor
Utilizzare il metodo ExceptBy per eseguire operazione di sottrazione tra liste
Eseguire i worklow di GitHub su runner potenziati
Path addizionali per gli asset in ASP.NET Core MVC
Utilizzare una qualunque lista per i parametri di tipo params in C#
Eseguire una ricerca avanzata per recuperare le issue di GitHub
Potenziare la ricerca su Cosmos DB con Full Text Search
Utilizzare Hybrid Cache in .NET 9
Documentare i servizi REST con Swagger e OpenAPI con .NET 9