Se la nostra web application fa uso di ruoli, abbiamo tipicamente la necessità di mostrare un messaggio di "Accesso non autorizzato" nel caso in cui un utente cerchi di visitare una sezione del sito per cui non dispone dei necessari permessi.
Nel caso di ASP.NET MVC una possibile soluzione è quella di realizzare una action Unauthorized e di configurarla come loginUrl della forms authentication:
<authentication mode="Forms"> <forms loginUrl="~/Account/Unauthorized" timeout="2880" /> </authentication>
Supponiamo ora che un utente loggato provi a visitare un controller su cui non è autorizzato, ad esempio perché il suo uso è ristretto ai soli membri del gruppo Administrators:
[Authorize(Roles = "Administrators")] public class BackOfficeController : Controller { public ActionResult Index() { return this.View(); } }
In questo caso, la forms authentication farà scattare il redirect verso la action che abbiamo configurato che, a sua volta, restituirà una view contenente un opportuno messaggio di errore:
public ActionResult Unauthorized() { if (User.Identity.IsAuthenticated) { // Non sei autorizzato a visitare questa pagina... return this.View(); } var routeValues = this.RouteData.Values; foreach (var key in this.Request.QueryString.AllKeys) { routeValues.Add(key, this.Request.QueryString[key]); } return this.RedirectToAction("LogOn", routeValues); }
Questo comportamento permane solo nel caso in cui l'utente sia autenticato ossia, in altre parole, quando il redirect ha avuto luogo per una mancanza di permessi. Nel caso in cui l'utente sia anonimo, invece, deve essere ripristinato il funzionamento tradizionale, rimandando pertanto alla pagina di login: la seconda parte del metodo si occupa proprio di assolvere a questo compito, avendo cura di includere nell'URL tutti gli eventuali parametri (sia di querystring che di routing) con cui Unauthorized è stata invocata.
Un piccolo difetto di questo approccio è che, nel caso di utente non autenticato, vengono effettuati due redirect successivi, uno verso la action Unauthorized e il successivo su quella di LogOn. In realtà potrebbe essere più indicato un comportamento simile al Server.Transfer di ASP.NET Web Forms, ed evitare così un roundtrip addizionale verso il browser. Purtroppo questo metodo non è direttamente utilizzabile in ASP.NET MVC, ma comunque in rete si trovano diversi esempi di come implementare un TransferResult e migliorare, se necessario, anche questo aspetto.
Commenti
Per inserire un commento, devi avere un account.
Fai il login e torna a questa pagina, oppure registrati alla nostra community.
Approfondimenti
Utilizzare Azure Cosmos DB con i vettori
Creare una custom property in GitHub
Generare un hash con SHA-3 in .NET
C# 12: Cosa c'è di nuovo e interessante
Supportare il sorting di dati tabellari in Blazor con QuickGrid
Eseguire query verso tipi non mappati in Entity Framework Core
Configurare il nome della run di un workflow di GitHub in base al contesto di esecuzione
Ordinare randomicamente una lista in C#
Eseguire le GitHub Actions offline
Utilizzare il nuovo modello GPT-4o con Azure OpenAI
Gestire domini wildcard in Azure Container Apps
Cancellare una run di un workflow di GitHub