Magazine

Persistenza della password in ViewState

Andrea Dottor

03/07/2006

In alcuni scenari è utile poter salvare in viewstate la password dell'utente, per consentirgli di cambiare visualizzazione evitando di dover digitare nuovamente la password. in questo tip viene illustato un modo per raggiungere questo scopo.

0%100%
per esprimere un voto è necessario registrarsi al sito

ASP.NET

textBoxModePassword.zip (7,00 Kb)

Un problema che affligge le TextBox con TextMode   = TextBoxMode.Password, è il fatto di non mantenere il valore digitato dopo un PostBack. Questo comportamento è dovuto a motivi di sicurezza facilmente comprensibili, ma dal punto di vista della programmazione talvolta porta noiosi inconvenienti.
Volendo ovviare a questo problema, potremmo creare uno UserControl che estende le funzionalità della TextBox persistendo la password inserita in ViewState.
Useremo una funzione che inseriremo nell'evento TextChanged della TextBox che si occuperà di questo salvataggio, e successivamente andremo a scrivere un valore fittizio nel tag value del HTML (quest'ultimo perchè il tag value non ha problemi di persistenza e useremo un testo fittizzio perchè il tag value risulterà visibile nel sorgente della pagina, e quindi non sarebbe sicuro se la nostra TextBox dovesse contenere dati sensibili quali la password od altro).

Partiamo con l'aggiungere al nostro progetto un nuovo WebUserControl.
Selezioniamo il progetto o la cartella che dovrà contenere il nuovo controllo e dal menu Project selezioniamo Add New Item e successivamente WebUserControl.ascx. Una volta creato il controllo andiamo a modificare il file cs corrispondente aggiungendo alla collezione dei controlli del nostro UserControl una TextBox che successivamente andremo ad estendere.

using System;
using System.Web;
using System.Web.UI.WebControls;
using System.Text;

public partial class WebUserControl : System.Web.UI.UserControl
{
   TextBox textBox = new TextBox();

   protected void Page_Load(object sender, EventArgs e)
   {
      this.Controls.Add(textBox);
   }
}

Creiamo due proprietà, TextBoxText che si occuperà della persistenza del dato Text e che ci servirà per reperire lo stesso, e TextMask che ci servirà per un testo di mascheramento che faremo vedere al posto dei nostri dati.

/// <summary>
/// Testo della textbox salvato in ViewState
/// </summary>
public string TextBoxText
{
   get { return GetViewState<string>("textBoxText", string.Empty); }
   set { SetViewState<string>("textBoxText", value); }
}
/// <summary>
/// Testo che maschererà il testo della TextBox
/// </summary> 
public string TextMask
{
   get { return GetViewState<string>("textMask", "testoDiMascheramento"); }
   set { SetViewState<string>("textMask", value); }
}

Ora dobbiamo creare una funzione che si occupi del recupero del testo inserito dalla TextBox e che lo persista nella property TextBoxText. Questa funzione la agganciamo all'evento TextChanged, in modo di salvare il dato dopo la sua modifica. Per fare questo agiamo all'interno del evento OnInit del nostro controllo.

protected override void OnInit(EventArgs e)
{
   textBox.TextChanged += delegate { SaveTextOnViewState(); };
   textBox.TextMode = TextBoxMode.Password; < BR >    this.Controls.Add(textBox);
   base.OnInit(e);
}
/// <summary>
/// Salvataggio dati in ViewState e mascheramento testo inserito
/// </summary>
private void SaveTextOnViewState()
{
   if ((textBox.Text != TextMask) &&
          (((string.IsNullOrEmpty(TextBoxText)) && (!string.IsNullOrEmpty(textBox.Text))) ||
                    (textBox.Text != TextBoxText)))
   {
       TextBoxText = textBox.Text;
       textBox.Attributes["value"] = TextMask;
   }    if ((string.IsNullOrEmpty(textBox.Text)) && (!string.IsNullOrEmpty(TextBoxText)))
       textBox.Attributes["value"] = TextMask;
}

Infine scriviamo le proprietà per accedere ai dati in ViewState facendo uso dei generic.

/// <summary>
/// Recupero del dato dalla ViewState
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="name">Nome del dato da recuperare</param>
/// <param name="defaultValue">Valore di default di ritorno se non è presente il dato in ViewState</param>
/// <returns></returns>
protected T GetViewState<T>(string name, T defaultValue)
{
   if (ViewState[name] == null)
            ViewState[name] = defaultValue;
   return (T)ViewState[name];
}




/// <summary>
/// Salvataggio dato in ViewState
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="name">Nome del dato da salvare</param>
/// <param name="value">Valore da salvare</param>
protected void SetViewState<T>(string name, T value)
{
   ViewState[name] = value;
}

Nel codice di esempio disponibile per il download è stato anche implementato un javascript per impedire che venga modificato il testo di mascheramento quando visualizzato.
Ecco come in modo elegante siamo riusciti a risolvere questo incoveniente delle TextBox e abbiamo così creato un nostro UserControl riusabile ad ogni occorenza.

E' bene evidenziare che salvare il dato in ViewState, o persistere dati sensibili sotto qualsiasi forma non è certamente una cosa sicura, ma ci sono alcuni casi in cui questa soluzione è applicabile. Ricordiamoci infatti che in una pagina non protetta dal protocollo https la password è comunque un dato che passa in plain-text.
Questo tip può essere da guida e applicato ad un qualsiasi controllo quando c'è bisogno di far persistere un dato dopo diversi postback e non necessariamente solo su TextBox con TextMode = TexBoxMode.Password

Commenti
Nome

Sito web
Commento


indietro