ASP.NET Identity implementa un sistema di security basato su claim. Possiamo pensare a un claim come a una caratteristica di un profilo utente, rilasciata da una authority. Per esempio, quando sfruttiamo Facebook come authority per l'autenticazione, tra i vari claim ci viene restituito l'indirizzo email dell'utente, che nel template di default di ASP.NET MVC, viene utilizzato per popolare il profilo utente.
Nel caso in cui abbiamo attivato la gestione dei ruoli, come mostrato in uno script precedente (https://www.aspitalia.com/script/1194/Usare-RoleManager-Gestire-Ruoli-ASP.NET-Identity.aspx), invece, ogni ruolo corrisponde a uno specifico claim inserito all'interno del principal corrente.
Un claim, da un punto di vista strettamente pratico, non è altro che una coppia chiave-valore, in cui possiamo anche noi memorizzare un'informazione personalizzata. Per esempio, immaginiamo di aver realizzato un gestionale aziendale, e di voler assegnare a un utente un ruolo specifico a seconda dell'anno di esercizio selezionato. L'utente User1, quindi, avrà ruolo Administrator nel 2014 e SuperUser nel 2015.
Possiamo allora creare due claim specifici e aggiungerli al profilo utente:
var userId = this.User.Identity.GetUserId(); string yearRoleClaimType = "http://mycustomapp/roles/year/{0}"; var claim1 = new Claim( string.Format(yearRoleClaimType, 2014), "Administrator"); var claim2 = new Claim( string.Format(yearRoleClaimType, 2015), "SuperUser"); await this.UserManager.AddClaimAsync(userId, claim1); await this.UserManager.AddClaimAsync(userId, claim2);
Il codice in alto come prima cosa recupera l'identificativo dell'utente corrente tamite GetUserId. Si tratta di un extension method, per il quale è necessario aggiungere il namespace Microsoft.AspNet.Identity. Poi crea due claim custom, il cui type specifica l'anno a cui si riferiscono, e li aggiunge al profilo utente tramite l'ApplicationUserManager.
A questo punto i nuovi claim sono memorizzati sul database e siamo pronti per verificarli in fase di autorizzazione su un controller o una action:
[AuthorizeByYear(Roles = "Administrator")] public ActionResult About() { ViewBag.Message = "Your application description page."; return View(); }
La action in alto usa l'attributo custom AuthorizeByYear per verificare che l'utente appartenga al ruolo specificato nell'anno di esercizio in corso. Questo attributo eredita dall'AuthorizeAttribute standard e ne ridefinisce il metodo AuthorizeCore:
protected override bool AuthorizeCore(HttpContextBase httpContext) { int currentYear = 0; if (!int.TryParse(httpContext.Request.QueryString["year"], out currentYear)) return base.AuthorizeCore(httpContext); string yearRoleClaimType = "http://mycustomapp/roles/year/{0}"; var claimType = string.Format(yearRoleClaimType, currentYear); var principal = (ClaimsPrincipal)httpContext.User; var authorized = principal.Claims // filtro tutti i claim type desiderati .Where(x => x.Type == claimType) // controllo che ci sia un claim del ruolo voluto .Any(x => x.Value == this.Roles); return authorized; }
Per semplificare, abbiamo supposto che l'anno di esercizio sia specificato come parametro in querystring. Se non presente, rimandiamo alla gestione base, altrimenti possiamo ricostruire il ClaimType desiderato e verificare che tra i claim presenti nel principal, ne sia presente almeno uno con il ruolo voluto.
Commenti
Per inserire un commento, devi avere un account.
Fai il login e torna a questa pagina, oppure registrati alla nostra community.
Approfondimenti
Proteggere le risorse Azure con private link e private endpoints
Utilizzare Azure AI Studio per testare i modelli AI
Supportare la sessione affinity di Azure App Service con Application Gateway
Ordinare randomicamente una lista in C#
Il nuovo controllo Range di Blazor 9
Sfruttare gli embedding e la ricerca vettoriale con Azure SQL Database
Gestione degli stili CSS con le regole @layer
Recuperare l'ultima versione di una release di GitHub
Fissare una versione dell'agent nelle pipeline di Azure DevOps
Gestione file Javascript in Blazor con .NET 9
Gestire eccezioni nei plugin di Semantic Kernel in ASP.NET Core Web API
Triggerare una pipeline su un altro repository di Azure DevOps