Gestione personalizzata dei ruoli con i claim custom di ASP.NET Identity

di Marco De Sanctis, in ASP.NET Identity,

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

Visualizza/aggiungi commenti

| Condividi su: Twitter, Facebook, LinkedIn

Per inserire un commento, devi avere un account.

Fai il login e torna a questa pagina, oppure registrati alla nostra community.

Approfondimenti

I più letti di oggi