Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

Assegnare ruoli agli utenti

Fornire privilegi differenziati agli utenti usando la classe Roles
Fornire privilegi differenziati agli utenti usando la classe Roles
Link copiato negli appunti

Oltre a limitare l'accesso ad alcune aree di una applicazione web, possiamo decidere di fornire ad alcuni utenti dei privilegi diversi all'interno dell'applicazione stessa, costituendo dei gruppi di utenti con ruoli differenti tra loro.

Pensiamo ad un giornale online, ovvero un sito per la gestione di contenuti. Per essere costantemente aggiornato con le ultime notizie, ha bisogno di diverse figure professionali. I giornalisti invece di scrivere su carta, scrivono direttamente sul sito. Ogni giornalista avrà a disposizione le sue pagine e sarà responsabile del loro contenuto. È chiaro che un giornalista non deve avere la possibilità di modificare le pagine assegnate agli altri.

Poi ci sarà una figura professionale che si occuperà della gestione dell'intero sito. In genere questa figura è chiamata amministratore. Questi avrà il compito di assegnare le pagine ai giornalisti e dovrà possedere maggiori privilegi del giornalista per accedere a delle parti del sito alle quali altri non possono accedere.

Quindi si capisce la necessità di assegnare ruoli diversi ai vari gruppi di utenti, con i relativi privilegi. In questo articolo vedremo come assegnare i ruoli agli utenti e come definire i privilegi di un ruolo sul file di configurazione del sito, il Web.config.

Per assegnare i ruoli agli utenti, ASP.NET 2.0 mette a disposizione il WAT, cioè il tool di amministrazione del sito.

Possiamo anche creare la nostra pagina personalizzata per assegnare i ruoli scrivendo qualche riga di codice ed utilizzando la classe Roles.

Vediamo con un esempio come utilizzare il WAT per definire i ruoli degli utenti. A tale scopo partiamo dall'esempio realizzato nell'articolo "Utilizzare il CreateUserWizard" che possiamo scaricare da qui e rinominare con nome "RuoliUtenti".

Il nome dell'applicazione (applicationName) all'interno del Membership Provider definito nel Web.config, può rimanere invariato in modo da poter utilizzare i dati già inseriti. Se preferiamo usare il Membership Provider di default, togliamo la sezione <membership> dal Web.config. In ogni caso, se non abbiamo i dati, creiamo con il WAT alcuni utenti come ad esempio quelli mostrati in figura:

Figura 1. Stato iniziale: utenti
Stato iniziale: utenti

Chi non sa utilizzare il WAT per inserire gli utenti, può riferirsi al capitolo Sicurezza della Guida ASP.NET 2.0.

Se nel nostro progetto abbiamo avviato il WAT e ci troviamo nella situazione visualizzata in figura 1, clicchiamo sul pulsante Indietro in basso a destra.

Nel riquadro Ruoli clicchiamo su Attiva ruoli. Una volta abilitati i ruoli, clicchiamo su Crea o gestisci ruoli. Appare un maschera in cui inserire il nome del ruolo che vogliamo creare. Inseriamo quindi un nome di ruolo per l'amministratore, ad esempio Admin.

Figura 2. Creazione del ruolo Admin
Creazione del ruolo Admin

Clicchiamo quindi su Aggiungi Ruolo. Il ruolo viene creato e visualizzato nella medesima pagina.

Per aggiungere un utente al ruolo Admin clicchiamo sul link Gestisci presente nella colonna Aggiungi/Rimuovi utenti.

Mettiamo poi l'asterisco nel campo di ricerca per visualizzare tutti gli utenti. Quindi all'utente "Asdrubale" assegniamo il ruolo Admin spuntando la casella corrispondente nella colonna Ruolo dell'utente:

Figura 3. Assegnazione del ruolo Admin all'utente Asdrubale
Assegnazione del ruolo Admin all'utente Asdrubale

In questo modo Asdrubale diventa un membro del ruolo "Admin".

Ora, all'interno del nostro progetto, nella cartella "Inscritti", creiamo la cartella "Amministratore" ed all'interno di essa mettiamo un nuovo Web Form che possiamo chiamare DefaultAdmin.aspx.

Per effettuare un test, mettiamo un'altra pagina nella cartella "Amministratore". Poi, per poter navigare da una pagina all'altra, mettiamo dei link fra le varie pagine e scriviamo qualcosa per riconoscerle.

All'interno della cartella "Amministratore" mettiamo anche un file di configurazione con una sezione <authorization>.

Listato 1. Web.config della cartella Amministratore


<configuration>
  <appSettings/>
  <connectionStrings/>
  <system.web>

    <authorization>
      <allow roles="Admin"/>
      <deny users="*"/>
    </authorization>

  </system.web>
</configuration>

A questo punto possiamo fare un test per verificare che solo l'utente Asdrubale possa accedere alle pagine dell'amministratore.

Figura 4. Test di accesso dell'utente con ruolo Admin
Test di accesso dell'utente con ruolo Admin

La classe Roles

In questa parte dell'articolo vediamo come creare i ruoli ed assegnarli agli utenti senza usare il WAT ma utilizzando la classe Roles.

Aggiungiamo un nuovo Web Form alla cartella Amministratore e chiamiamolo "Ruoli.aspx". e vi inseriamo una tabella come mostrato in figura.

Figura 5. Ruoli.aspx
Ruoli.aspx

La prima riga descrive il contenuto della seconda riga.

Nella seconda riga abbiamo una ListBox per elencare i ruoli (ListBoxRuoli), una ListBox per elencare gli utenti (ListBoxUtenti) che hanno il ruolo selezionato nella lista dei ruoli ed un'altra ListBox per elencare gli utenti che invece non fanno parte del ruolo selezionato.

Le liste degli "Utenti nel ruolo" e quella degli "Utenti fuori" serviranno anche ad assegnare o a togliere agli utenti il ruolo selezionato.

Nella quarta riga della tabella abbiamo una casella di testo per inserire il nome di un nuovo ruolo (TextBoxNewRuolo) ed un pulsante per inserire il ruolo nel database (ButtonAddRuolo).

Nell'ultima riga della tabella abbiamo una checklist (CheckBoxListRuoli) per elencare i ruoli, con la possibilità di selezionarne uno o più di uno per la cancellazione dal database, che avverrà cliccando sul pulsante Conferma cancellazione (ButtonDelete).

È inoltre presente un'etichetta in rosso per visualizzare eventuali messaggi.

Definita l'interfaccia utente dobbiamo implementare i metodi che gestiscono la visualizzazione, l'inserimento e la cancellazione dei ruoli nonché la gestione degli utenti appartenenti ai ruoli, quindi implementare anche l'inserimento e l'eliminazione degli utenti dai ruoli.

Cominciamo ad implementare il metodo per popolare la ListBoxRuoli e la CheckBoxListRuoli.

Listato 2. PopolamentoListeRuoli()

protected void PopolamentoListeRuoli()
{
  string[] ruoli;
  ruoli = Roles.GetAllRoles();
  ListBoxRuoli.Items.Clear();
  CheckBoxListRuoli.Items.Clear();
  for (int i = 0; i < ruoli.Length; i++)
  {
    ListBoxRuoli.Items.Add(ruoli[i].ToString());
    CheckBoxListRuoli.Items.Add(ruoli[i].ToString());
  }
}

Questo metodo parte con la definizione di un array di stringhe (ruoli), che servirà da contenitore per i nomi dei ruoli presenti nel database, ed utilizza il metodo GetAllRoles() della classe Roles, per riempire l'array. Il resto del codice serve a cancellare le due liste, per popolarle nuovamente con dati aggiornati.

Implementiamo adesso il metodo per popolare le liste degli utenti.

Listato 3. PopolamentoListeUtenti()

protected void PopolamentoListeUtenti()
{
  ListBoxUtenti.Items.Clear();
  if (ListBoxRuoli.SelectedItem != null)
  {
    string[] utentiInRuolo = Roles.GetUsersInRole(ListBoxRuoli.SelectedItem.ToString());
    for (int i = 0; i < utentiInRuolo.Length; i++)
      ListBoxUtenti.Items.Add(utentiInRuolo[i].ToString());
      // popolamento lista ListBoxUtentiNon

      ListBoxUtentiNon.Items.Clear();
      MembershipUserCollection utenti = Membership.GetAllUsers();
      foreach (MembershipUser UserName in utenti)
        if (!Roles.IsUserInRole(UserName.ToString(), ListBoxRuoli.SelectedItem.ToString()))
          ListBoxUtentiNon.Items.Add(UserName.ToString());
  }
}

Questo metodo cancella i dati della ListBoxUtenti, controlla poi che ci sia un elemento selezionato sulla ListBoxRuoli perché è da questo dato che si estraggono le due liste.

Riempie poi l'array di stringhe utentiInRuolo utilizzando il metodo GetUsersInRole della classe Roles. Il metodo GetUsersInRole prende in input il nome del ruolo e restituisce tutti gli utenti che ne fanno parte.

Per popolare la seconda lista dobbiamo prendere tutti gli utenti che non fanno parte di quel ruolo. Estraiamo quindi la Collection utenti dal database per mezzo del metodo GetAllUsers() della classe Membership. Per ogni utente estratto, controlliamo che non faccia parte del ruolo per mezzo del metodo IsUserInRole e quindi popoliamo la lista. IsUserInRole, usato con due parametri, il nome utente ed il ruolo, ci restituisce un valore booleano che è true se l'utente appartiene al ruolo.

Gestione dei pulsanti.

Nell'interfaccia utente abbiamo la TextBox TextBoxNewRuolo che serve ad inserire un ruolo nel database mediante immissione del suo nome che lo identificherà univocamente.

Una volta inserito il nome del nuovo ruolo nella TextBoxNewRuolo, cliccando sul pulsante ButtonAddRuolo il nuovo ruolo viene aggiunto.

Dobbiamo quindi implementare il gestore dell'evento OnClick sul pulsante ButtonAddRuolo.

Listato 4. Gestore dell'evento OnClick sul pulsante ButtonAddRuolo

protected void ButtonAddRuolo_Click(object sender, EventArgs e)
{
  if (!Roles.RoleExists(TextBoxNewRuolo.Text))
  {
    Roles.CreateRole(TextBoxNewRuolo.Text);
    ListBoxRuoli.Items.Add(TextBoxNewRuolo.Text);
    CheckBoxListRuoli.Items.Add(TextBoxNewRuolo.Text);
  }
  else
    LabelMsg.Text= "Ruolo " + TextBoxNewRuolo.Text + " già esistente";
}

Questo metodo verifica l'esistenza del ruolo che si vuole inserire. Infatti non si possono inserire due ruoli con lo stesso nome, se provassimo a farlo, il Membership Provider solleverebbe un'eccezione.

La creazione del nuovo ruolo avviene mediante la chiamata del metodo CreateRole della classe Roles, cui passiamo il nome del nuovo ruolo. Se il ruolo già esiste mandiamo un messaggio all'amministratore.

L'altra cosa che dobbiamo fare è aggiungere il nuovo ruolo alla due liste dei ruoli presenti nell'interfaccia utente: la ListBoxRuoli e la CheckBoxListRuoli.

Il ButtonDelete serve a cancellare il ruolo spuntato nella CheckBoxListRuoli. Implementiamo il gestore del click sul ButtonDelete.

Listato 5. Gestore dell'evento OnClick sul pulsante ButtonDelete

protected void ButtonDelete_Click(object sender, EventArgs e)
{
  for (int i = 0; i < CheckBoxListRuoli.Items.Count; i++)
    if (CheckBoxListRuoli.Items[i].Selected)
    {
      Roles.RemoveUsersFromRole(Roles.GetUsersInRole(CheckBoxListRuoli.Items[i].Text),
CheckBoxListRuoli.Items[i].Text);
      Roles.DeleteRole(CheckBoxListRuoli.Items[i].Text);
    }
  
  PopolamentoListeRuoli();
  PopolamentoListeUtenti();
}

Il ButtonDelete_Click prende l'elemento (o gli elementi) selezionato nella checklist e, prima rimuove tutti gli utenti dal ruolo che si vuole cancellare mediante il metodo RemoveUsersFromRole, e poi, cancella il ruolo per mezzo del metodo DeleteRole. È necessario togliere prima tutti gli utenti perché non si può cancellare un ruolo che non sia vuoto.

Infine il ButtonDelete_Click ripopola le liste dei ruoli e degli utenti prive del ruolo cancellato.

Page_Load

Listato 6. Implementazione del Page_Load

protected void Page_Load(object sender, EventArgs e)
{
  if (!Page.IsPostBack)
    PopolamentoListeRuoli(); // popolamento liste ruoli

  PopolamentoListeUtenti(); // popolamento lista utenti in ruolo
}

Il Page_Load si occupa solo di chiamare i metodi per popolare le liste che abbiamo già esaminato.

Affinché il tutto funzioni, dobbiamo anche implementare il gestore dell'evento Page_PreLoad che viene lanciato con il vecchio view state.

Listato 7. Implementazione del Page_PreLoad

protected void Page_PreLoad(object sender, EventArgs e)
{
  if (ListBoxUtentiNon.SelectedItem != null)
    Roles.AddUserToRole(ListBoxUtentiNon.SelectedValue, ListBoxRuoli.SelectedValue);

  if (ListBoxUtenti.SelectedItem != null)
    Roles.RemoveUserFromRole(ListBoxUtenti.SelectedValue, ListBoxRuoli.SelectedValue);
}

L'esigenza di usare il Page_PreLoad nasce dal fatto che quando vogliamo ad esempio aggiungere un utente ad un ruolo, dobbiamo prelevarlo dalla ListBoxUtentiNon ed al prossimo PostBack visualizzarlo nella lista ListBoxUtenti. Queste due liste sono però popolate partendo dal ruolo selezionato nella lista ListBoxRuoli che non appena avviene il PostBack ripopola le due liste facendo perdere il SelectedValue precedente.

Durante l'esecuzione di Page_PreLoad abbiamo ancora a disposizione il valore selezionato ed il ripopolamento avviene successivamente nel Page_Load.

Inoltre, nelle liste ListBoxRuoli, ListBoxUtenti e ListBoxUtentiNon, dobbiamo impostiare la proprietà: AutoPostBack="True".

A questo punto possiamo testare la nostra pagina Ruoli.aspx e verificare che il tutto funzioni.

Entriamo come Admin, cioè con l'utente Asdrubale. Selezionando il ruolo Admin sulla prima lista ci troviamo nella seguente situazione:

Figura 6. Test: situazione iniziale
Test: situazione iniziale

L'applicazione riconosce un solo ruolo Admin assegnato solo all'utente "Asdrubale". Gli altri utenti sono visualizzati nella lista degli Utenti fuori.

Aggiungiamo un nuovo ruolo specificando un nome diverso da Admin. Ad esempio Risorse e lo assegnamo agli utenti Pippo e Pluto. Per farlo selezioniamo Risorse sulla lista dei Ruoli e poi Pippo e Pluto sulla lista degli Utenti fuori. Appena selezionato, un utente passa da una lista all'altra.

Alla fine di questa operazione lo scenario diventa il seguente:

Figura 7. Test: dopo aver aggiunto Risorse e spostato Pippo e Pluto
Test: dopo aver aggiunto Risorse e spostato Pippo e Pluto

Anche la lista Cancella ruoli si è aggiornata.

Proviamo ora ad aggiungere NonnaPapera a Risorse e poi a toglierla per verificare che funziona anche il passaggio inverso.

Verifichiamo che aggiungendo di nuovo il ruolo Risorse ci ritorna un messaggio di errore. Verifichiamo poi anche la cancellazione di un ruolo.

L'esempio sviluppato in questo articolo, privato del database per comodità, può essere scaricato da qui.

Ti consigliamo anche