Autenticazione di ASP.NET: Forms Authentication con roles

3 pagine in totale: <<Indietro 1 2 [3]

Il codice più importante, come si è capito, è quello presente nel global.asax e dell'evento

void Application_AuthenticateRequest(Object s, EventArgs e)

Quando testai per la prima volta qualche mese fa l'autorizzazione basata sui Foms con i roles incontrai un problema: come potevo trasferire il role dalla pagina di login per ogni singolo utente in questa routine nel global.asax?

Se si rilegge il codice riportato qualche passaggio fa, si vedrà che i roles vengono definite esplicitamente ("gruppo1" e "gruppo2") attraverso un array.

Ovviamente in un esempio reale dove gli utenti e i roles sono presi da un database, bisogna cambiare un attimo il codice.

public void Application_AuthenticateRequest(Object s, EventArgs e)
{
  if (Request.IsAuthenticated) {
  string nome=User.Identity.Name;
  string[] arr=new string[]{"gruppo1","gruppo2"}; // da dove prelevo questa informazione?
  GenericIdentity identita=new GenericIdentity(nome);
  Context.User= new GenericPrincipal(identita,arr);
  }
  }

Per ogni pagina richiesta è necessario specificare per l'utente il relativo role, ma la soluzione che avevo trovato in vari tutorial non mi ha soddisfatto.

In poche parole, ad ogni accesso veniva effettuata una query su un database o una ricerca in un file XML per trovare i roles relativi all'utente.

Personalmente lo ritengo uno spreco di risorse inutile. La prima soluzione che pensai fu l'utilizzo delle variabili Session (memorizzavo la role in una variabile session che richiamavo nella routine qui sopra per la creazione dell'array), ma dovetti scartare questa soluzione perché da questo evento è impossibile utilizzare questo oggetto (si otterrebbe l'errore: System.Web.HttpException: Session state is not available in this context). Nell'esempio che trovate allegato a questo articolo ho utilizzato un trucco banale ma molto funzionante: memorizzo i roles insieme al nome separati dai due punti ":". Ecco come il codice per il login:

if (user.Value==objDataReader["nome"].ToString() && pass.Value==objDataReader["password"].ToString()) {
  string nome=user.Value+":"+objDataReader["role"];
  FormsAuthentication.RedirectFromLoginPage(nome,false);

  }

Una volta che si è controllato l'esattezza dell'user name e della password, viene memorizzato il nome e la relativa "role" presa dal database separati dai due punti ":" come nome autenticato. Ora, nel nostra routine nel global.asax abbiamo tutte le informazioni che desideriamo:

public void Application_AuthenticateRequest(Object s, EventArgs e)
{
  if (Request.IsAuthenticated) {
  string role,nome=User.Identity.Name;
  role=nome.Substring(nome.IndexOf(":")+1);
  string[] arr=new string[]{role};
  GenericIdentity identita=new GenericIdentity(nome);
  Context.User= new GenericPrincipal(identita,arr);
  }
  }

Se vogliamo visualizzare il nome con cui ci siamo autenticati nelle nostre pagine ASP.NET ci è sufficiente scrivere (come nelle pagine presenti nelle sottodirectory):

string nome=User.Identity.Name;
nome=nome.Substring(0,nome.IndexOf(":"));
Label1.Text=nome;

Naturalmente, possiamo controllare le relative roles per ogni utente:

if (User.IsInRole("Admin")) Response.Write ("Role: Admin");
if (User.IsInRole("Manager")) Response.Write ("Role: Manager");
if (User.IsInRole("Utente")) Response.Write ("Role: Utente");

Nell'esempio viene impostato enabled=false sui link; questo comporta con IE che il link è ancora cliccabile ma viene visualizzato con un colore grigio.

Infine, come giustamente intuibile, cliccando su un link di una directory di cui non si hanno le autorizzazioni, si verrà inviati nuovamente alla pagina di Login. Questo comportamento non è molto intuibile ad un qualsiasi utente. Sarebbe meglio visualizzare un messaggio di errore del tipo "Il nome utente con cui ti sei autenticato non ha sufficienti autorizzazioni...". Nell'esempio, rimando l'utente ad una pagina di errore grazie al codice:

if (Request["ReturnUrl"]!=null && User.Identity.Name!="" )
  Response.Redirect ("Error.aspx");

Conclusioni

Con questo articolo e l'esempio allegato spero di aver fatto chiarezza sull'utilizzo delle roles con l'autenticazione Forms presente in ASP.NET. Questa è una possibile soluzione e implementazione. E' possibile assegnare ad ogni utente più "roles" (ad esempio, un role, una directory), ma personalmente preferisco l'approccio, per semplificazione e gestione, di un role per utente, come nell'esempio.

Comunque invito il lettore a provare entrambe le soluzioni per constatare di persona qualche sia la tecnica migliore per i propri scopi.

Approfondimenti

3 pagine in totale: <<Indietro 1 2 [3]

Attenzione: Questo articolo contiene un allegato

Contenuti dell'articolo

Commenti
Dai un voto a questo articolo, ci aiuterà a migliorare il nostro sito (1 è il voto minimo, 5 il massimo).

Per procedere al rating dell'articolo devi essere autenticato.
tyler77 scrive:
Autenticazione di ASP.NET: Forms Authentication con roles

Ciao, sono alle prese con le Roles di asp.net 2.0, ho letto il tuo tutorial ma ahimè una volta riadattato al mio misero progettino non funziona.E' ...
mercoledì 7 maggio 2008

Aggiungi un nuovo commento »»»
Per inserire un commento, devi registrarti alla nostra community.


TUTORIALS
TOP TEN ARTICOLI
NOTIFICHE

Iscriviti alla nostra newsletter nuoviarticoli per ricevere e-mail le notifiche!

Indirizzo e-mail:
PROVIDER ASP.NET 2.0

Seleziona il database per avere il web.config pronto per Membership, Roles e Profile API.



IN EVIDENZA
MISC