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
Usare un KeyedService di default in ASP.NET Core 8
Generare file PDF da Blazor WebAssembly con iText
Short-circuiting della Pipeline in ASP.NET Core
Potenziare Azure AI Search con la ricerca vettoriale
Esportare ed analizzare le issue di GitHub con la CLI e GraphQL
Sfruttare al massimo i topic space di Event Grid MQTT
Trasformare qualsiasi backend in un servizio GraphQL con Azure API Management
Ottenere il contenuto di una cartella FTP con la libreria FluentFTP
Sostituire la GitHub Action di login su private registry
Utilizzare domini personalizzati gestiti automaticamente con Azure Container Apps
Generare token per autenicarsi sulle API di GitHub
Effettuare il binding di date in Blazor