Gestione delle password in ASP


Home Page | Commenti | Articoli | Faq | Documenti | Ricerca | Archivio | Storie dalla Sala Macchine | Contribuire | Login/Register
A cura di Davide Bianchi In molte situazioni si vuole "restringere" l'accesso a certe risorse di un sito Web, puo' essere una pagina che consente il download di certi file, o l'accesso a certi documenti, o altre informazioni piu' o meno riservate.


Davide Bianchi, lavora come Unix/Linux System Administrator presso una societa' di "sicurezza informatica" (aka: $networkgestapo) di Haarlem. Contatti: mail: davide AT onlyforfun.net , Jabber: davideyeahsure AT gmail.com,

Volete contribuire? Leggete come!.
 
 

Il presente sito e' frutto del sudore della mia fronte (e delle mie dita), se siete interessati a ripubblicare uno degli articoli, documenti o qualunque altra cosa presente in questo sito per cortesia datemene comunicazione (o all'autore dell'articolo se non sono io), cosi' il giorno che faccio delle aggiunte potro' avvisarvi e magari mandarvi il testo aggiornato.


Questo sito era composto con VIM, ora e' composto con VIM ed il famosissimo CMS FdT.

Questo sito non e' ottimizzato per la visione con nessun browser particolare, ne' richiede l'uso di font particolari o risoluzioni speciali. Siete liberi di vederlo come vi pare e piace, o come disse qualcuno: "Finalmente uno dei POCHI siti che ancora funzionano con IE5 dentro Windows 3.1".

Web Interoperability Pleadge Support This Project
Powered By Gort
Il problema del Login Ok, abbiamo la pagina (o le pagine) da "proteggere", il problema e' come stabilire se l'utente che vuole accedere puo' farlo o meno.

Vi sono fondamentalmente due modi di "verificare" l'utente, il primo si basa sulla security implementata da Windows NT, quindi e' sicuramente piu' robusto, il secondo si basa su una login-fai-da-te per consentire o negare l'accesso.

La security di NT La Security di NT permette di specificare quali utenti hanno visibilita' sulle directory e sui singoli file. Se una directory del nostro sito Web non ha i permessi di lettura per tutti gli utenti, ma solo per alcuni, solo questi utenti saranno abilitati ad accedere alle pagine contenute.

Quindi, l'unica cosa da fare per "abilitare" un utente e' definirlo nel databsae utenti di Windows NT. Il browser visualizzera' automaticamente la maschera di Login per "validare" l'utente.

Problema: occorre mettere le mani nel database degli utenti di Windows NT, cosa che non si puo' fare sempre e comunque non da "remoto", occorre essere sul server o su una macchina connessa alla stessa rete fisica del server (nessun Amministratore e' cosi' pazzo da farci amministrare il server da remoto).

Login fai-da-te Per implementare il meccanismo di Login occorrono fondamentalmente 3 cose:
  1. un database che contenga gli utenti e le rispettive password
  2. una pagina che consenta all'utente di inserire nome e password e che faccia la validazione
  3. un "pezzo" di codice posto all'inizio di ogni pagina seguente che verifichi lo "stato" di login ed eventualmente rispedisca l'utente alla pagina di login se lo stato non e' "buono".
Cominciamo dal database Un database "minimo" per consentire la gestione di un Login deve contenere almeno le seguenti informazioni.

Tabella UTENTI:

Campo Tipo Commento Chiave
Nome testo Contiene il nome di login dell'utente Si
Password testo Contiene la password che l'utente deve digitare Si

NOTA: non ho aggiunto un campo "chiave univoca" perche' nome utente e password messe insieme devono gia' essere una chiave univoca.

E' possibile (ovviamente) aggiungere anche molte altre informazioni, ma per un sistema "minimo" queste due bastano. Teniamo anche conto delle varie leggi sulla privacy e sul trattamento dei dati personali prima di mettere due tonnellate di dati in questo database.

La pagina di login A questo punto ci vuole la "pagina" che consente il login (LOGIN.ASP)

Questa pagina richiama se' stessa ogni volta che l'utente preme il tasto "login", se la coppia utente/password viene trovata nel database, il nome dell'utente viene inserito in una apposita variabile di sessione userloggedin per riferimenti successivi, e l'utente viene rediretto su una pagina chiamata paginaprotetta.asp, se la coppia/utente password non viene trovata, la pagina visualizza un messaggio di errore e richiede di nuovo l'inserimento.


<SCRIPT LANGUAGE=JSCRIPT RUNAT=SERVER>
  
  var connection;
  var recordset;
  var password;
  var login;
  var sql;
  var reg1 = /!1/i;
  var reg2 = /!2/i;
  var userok = false;		
  
  /* preparo la stringa sql */
  sql = "SELECT * FROM UTENTI WHERE LOGIN='!1' AND PASSWORD='!2'"
  
  /* leggo i parametri dalla form */
  password = "" + request.form("password") + "";
  login    = "" + request.form("login") + "";
 
  /*************************************************/
  /*  NOTA: per evitare problemi di "SQL Inject",  */
  /* Sarebbe opportuno controllare che le stringhe */
  /* inserite dall'utente non contengano caratteri */
  /* "strani", come virgolette ' o segni di uguale */
  /* Segnalazione di WebMaster JSDir               */
  /*************************************************/

  /* verifico quello che l'utente ha scritto */
  if( login == "undefined" )
  {
    /* Non ho ancora chiesto niente, visualizzo la form e basta */
  }
  else
  {
  
    /* Apro la connessione al database */
    connection = new ActiveXObject("ADODB.Connection");

    /* ********************************************* */    
    /* ********************************************* */    
    /* N.B. qui' occorre mettere la connessione vera (vedi nota)*/
    connection.open("test");
    /* ********************************************* */    
    /* ********************************************* */    
    
    /* verifico se l'utente esiste */
    
    /* sostituisco i parametri nella stringa SQL */
    sql = sql.replace( reg1, login );
    sql = sql.replace( reg2, password );
    
    /* eseguo Ricerca */
    recordset = connection.execute( sql );
    
    if( recordset.eof && recordset.bof )
    {
      /* utente non trovato */
      Response.write("<B>Utente non trovato o password errate.");
      Response.write("Ripetere prego</b><P>");
    }
    else
    {
      /* utente trovato, inserisco l'informazione nelle variabili 
      di sessione */
      userok = true;
      Session("userloggedin") = String(login);
    }
    
    /* chiudo il recordset qualunque cosa sia successa */
    recordset.close();
    
    /* chiudo la connessione */
    connection.close();
    
  }
  
  /* verifico se l'utente ha fatto login in modo appropriato */
  if( userok )
  {
    /* invio l'utente alla pagina protetta */
    response.redirect("paginaprotetta.html")
  }
  
  /* TERMINE DELLO SCRIPT */
</SCRIPT>

<HTML>
<BODY>
<H2>Esempio d'uso dello script per verifica user/password</H2>
Questa pagina presenta un esempio di maschera di login.<BR>
Nel database di esempio sono registrati i seguenti utenti:<br>
<ul>
<li><b>guest</b> con password <b>guest</b>
<li&ht;<b>iome</b> con password <b>password</b>
</ul>
Qualunque errore nell'immissione del nome utente o della
password impedira' l'accesso.<P>

<FORM METHOD=POST ACTION=LOGIN.ASP>
<table width=40% bgcolor=lightblue>
<tr><td></td>
<td> </td><td>
</td><td> </td></tr>
<tr>
<td width=5%> </td>
<td width=30%>Login:</td>
<td width=60%>
<INPUT TYPE=TEXT NAME=login VALUE="<%=Request("login")%>"></td>
<td width=5%> </td>
</tr>
<tr>
<td width=5%> </td>
<td>Password</td>
<td><INPUT TYPE=password NAME=password VALUE="<%=Request("password")%>"></td>
<td width=5%> </td>
</tr>
<tr>
<td>   <P>   </td>
<td> </td>
<td><input type=submit value="Login"></td>
<td> </td>
</tr>
</table>
</FORM>
</center>

Per verificare la non-accessibilita' della pagina fare click qui:
 <a href="paginaprotetta.asp">Pagina protetta</a><br>
si verra' rimandati di nuovo alla pagina di Login.

</BODY>
</HTML>

NOTA: In questo codice si fa riferimento ad una connessione ODBC denominata TEST, ovviamente voi dovrete sostituire a questa connessione la vostra connessione al database contenente la tabella degli utenti, eventualmente specificando la connessione DSN-LESS, vedere anche Asp e Database.

L'unica parte forse "oscura" di tutto il codice sono le due replace che mi permettono di ficcare login e password nella stringa SQL che viene usata successivamente. In questo caso ho utilizzato il metodo replace dell'oggetto String di JScript, che consente di usare una Regular Expression per sostituire all'interno di una stringa un'altra stringa.

Verifica sulle singole pagine Ok, questo mi consente di verificare un utente se esiste o meno nel mio database, la verifica pero' deve essere fatta su tutte le pagine che andiamo a gestire nell'area "protetta", per controllare che l'utente non faccia "il furbo" e cerchi di accedere direttamente alla pagina digitandone l'URL. Per questo abbiamo la variabile di sessione userloggedin. Mettendo il seguente codice all'inizio di ogni pagina (prima ancora dell') si effettua tale verifica:

<SCRIPT LANGUAGE=JSCRIPT RUNAT=SERVER>

  /* verifico se l'utente e' valido */
  var user = "" + Session("userloggedin") + "";
  
  if( user == "undefined" )
  {
    /* l'utente non ha fatto login o la sessione e' scaduta */
    /* rimando alla pagina di login */
    response.redirect("login.asp")
  }

</SCRIPT>
Se l'utente non viene considerato "valido", questo viene rimandato direttamente alla pagina di Login in modo che possa effettuare l'accesso in modo consentito.

Considerazioni finali Con il codice suggerito siamo in grado di "validare" un utente per l'accesso alle nostre pagine, questo non ci salva da tutti i problemi inerenti pero'. Per esempio non e' molto bello che la password del nostro utente sia inserita "in chiaro" nel database, andrebbe aggiunta una funzione di crittografia per evitare che la password possa essere vista da altri. Allo stesso modo sarebbe bene che la password potesse essere cambiata dall'utente, occorre una "pagina di amministrazione" insomma.

Allo stesso modo questo non e' sufficiente se si vuole proteggere un file che non e' una pagina ASP, in questo caso occorre fare le cose un poco piu' fini, ma questo e' un argomento per un altro articolo.

Come fatto notare da un lettore (Webmaster JsDir), il codice presentato non considera casi di "SQL Inject", in cui un'utente cerca di "falsificare" l'accesso aggiungendo caratteri particolari nei campi username e password (vedere anche http://www.4guysfromrolla.com/webtech/061902-1.shtml), percui sarebbe opportuno verificare che i campi inseriti non contengano caratteri come ', = o ".

I commenti sono aggiunti quando e soprattutto se ho il tempo di guardarli e dopo aver eliminato le cagate, spam, tentativi di phishing et similia. Quindi non trattenete il respiro.

2 messaggi this document does not accept new posts
stecolnastecolna Di stecolna - postato il 15/10/2008 13:26
Ottimo articolo, come al solito. Anche se ormai ASP una tecnologia superta, l'articolo contiene considerazioni valide anche in altri contesti informatici. (es SQL Injection)

joyjoy Di joy - postato il 04/12/2008 09:21

bellissimo articolo, sto imparando asp e il problema della sicurezza si ripropone sempre e sembra che l'accostamento al java sia molto ricorrente per avere form protetti.

Precedente Successivo