Redazione
a- a+

Creare un sistema di login per accedere in un'area riservata (II Parte)

Vediamo la seconda parte dell'articolo su come creare un sistema di login sicuro con ASP. In questo articolo verrà implementato un controllo dei dati nel database e login automatico.

Il progetto

Al sistema di login realizzato nell'articolo precedente, ora verrà implementato un controllo dei dati nel database e il login automatico

 

Dati:
    Utente 1
        Username: lorenzo
        Password: pascucci
    Utente 2
        Username: mario
        Password: gds933f
    Utente 3
        Username: rosa
        Password: 489das0u3

Le pagine utilizzate

Le pagine utilizzate per questo sistema sono le stesse utilizzate nella precedente lezione con alcune modifiche nel modulo e nella pagina di login. E' stata inoltre introdotta una seconda pagina da proteggere solo per rendere l'esempio piu' completo.

Utilizzando questo sistema l'utente potrà dopo il primo accesso:

  1. accedere le volte successive direttamente in una pagina protetta (senza fare il login)
  2. accedere al modulo trovando i dati di accesso già inseriti

Tutto questo grazie all'utilizzo dei Cookies. Il cookie permette di memorizzare dati importanti sul computer dell'utente. Sono spesso utilizzati appunto per i sistemi di autenticazione automatica.

Il modulo

Il modulo sarà necessario modificarlo in 2 punti:

  1. i campi text box
  2. la gestione degli errori

Vediamo come e perchè.

Un'importante funzionalità di un sistema di autenticazione è ricordare i dati di accesso nel modulo di login. Quindi dovremmo modificare i valori predefiniti dei 2 text box (campi di testo) inserendo 2 semplici istruzioni asp che prelevano i dati dal cookie (che verrà creato dalla pagina di login), se il cookie non è ancora stato creato (perché non è ancora stato effettuato alcun accesso) i campi risulteranno vuoti.

Per ricavare i dati da un cookie è necessario utilizzare l'istruzione:

Request.Cookies("nome")("nomevar")

dove nome è il nome del cookie e nomevar è il nome della variabile, in quanto uno stesso cookie può contenere piu' informazioni, in questo caso 3:

  • username
  • password
  • data di scadenza del cookie

Inoltre dalla gestione degli errori sarà necessario eliminare l'errore 102 in quanto non è previsto piu' questo controllo, infatti se i dati memorizzati nel cookie dell'utente che accede sono corretti è possibile entrare nelle pagine riservate da qualsiasi pagina.

Codice 8.1

<html>

<body>
<!--
www.webmasterpoint.org
-->
<!-- INIZIO Gestione visualizzazione errori -->
<%
err = Cint(Request.QueryString("err"))
If err > 100 then
%>
<p align="center"><font face="Verdana" size="1" color="#FF0000">
<b>IMPORTANTE:</b></font><font face="Verdana" size="1"><b>Errore </b>
<%
Select Case err

Case 101
Response.Write("UsernamePassword non corretti")

Case 103
Response.Write("Username e Password non possono contenere 
caratteri speciali per motivi di sicurezza")

End Select
%>
</font></p>
<%
End if
%>
<!-- FINE Gestione visualizzazione errori -->

<div align="center">
<center>
<form method="POST" action="lez08_index.asp">
<table border="1" width="438" height="29">
<tr>
<td width="131" height="16"><font face="Verdana" size="2">Username:
</font></td><td width="301" height="16">
<input type="text" name="username" size="20" 
value="<%=Request.Cookies("entra")("username")%>"></td>
</tr>
<tr>
<td width="131" height="13"><font size="2" face="Verdana">Password:
</font></td>
<td width="301" height="13">
<input type="password" name="password" size="20"
value="<%=Request.Cookies("entra")("password")%>"></td>
</tr>
<tr>
<td width="438" height="1" colspan="2">
<p align="center">
<input type="submit" value="Login &gt;&gt;&gt;" name="B1"></td>
</tr>
</table>
<input type="hidden" name="tipo" value="login">
</form>
</center>
</div>

</body>

</html>

Il cuore dello script
Il codice e la logica con cui viene effettuato il controllo dei dati, come è stato già anticipato, è leggermente differente, vediamo le modifiche apportate:

  • controllo del login dal modulo eliminato
  • memorizzazione su cookie
  • controllo dati su database
  • controllo dei dati memorizzati sul cookie

Con questo sistema non è necessario effettuare il login esclusivamente dal modulo. Infatti grazie all'utilizzo dei cookie è possibile accedere all'area riservata da una qualsiasi sua pagina.

La memorizzazione di un cookie è molto semplice:

Response.Cookies("nome")("nome")

Quindi basta fare: Response.Cookies("nome")("nome") = valore.

Codice 8.2

<%
'*******************************************************
'** www.webmasterpoint.org
'*******************************************************


'Funzione che controlla l'inserimento 
'di caratteri accettabili o meno
public function check_nick (allow, nick)
  nick = nick
  check_nick = true
  for i = 1 to len(nick)
    if instr(allow, mid(nick,i,1)) = 0 then check_nick = false
  next
end function

'Controllo se è già stato effettuato l'accesso
If Session("permesso_entrata") <> True then

  'Controllo se è stato effettuato l'accesso dal modulo di login
  Dim tipo
  tipo = Request.Form("tipo")

  'Acquisisco i dati di accesso
  Dim username, password
  username = Trim(Request.Form("username")) 
  password = Trim(Request.Form("password"))

  'Controllo l'eventuale inserimento di caratteri 
  'speciali (non sono autorizzati, per motivi di sicurezza)
  if check_nick ("abcdefghijklmnopqrstuvwxyz -->
-->ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", username) = false then
    response.redirect("lez08_modulo.asp?err=103")
  end if

  if check_nick ("abcdefghijklmnopqrstuvwxyz -->
-->ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", password) = false then
    response.redirect("lez08_modulo.asp?err=103")
  end if

  'Se è stato effettuato il login dal modulo entra
  If tipo = "login" then
    Response.Cookies("entra")("username") = username
    Response.Cookies("entra")("password") = password
    Response.Cookies("entra").Expires = date()+365
  End If

  'Connessione al database
  Set db = Server.CreateObject("ADODB.Connection")
  db.Open "provider=microsoft.jet.oledb.4.0;data source=" _
& Server.MapPath("lez08_iscritti.mdb")

  'Controllo dei dati inseriti nel modulo per il 
  'riconoscimento con un database

  us = Request.Cookies("entra")("username")
  ps = Request.Cookies("entra")("password")

  Set rsLogin = db.Execute("SELECT * FROM utenti WHERE _
  UserName = '" & us & "' AND Password = '" & ps & "'")
  If rsLogin.EOF Then

    Session("permesso_entrata") = False
    Response.Redirect "lez08_modulo.asp?err=101"

  Else 

    Session("permesso_entrata") = True

  End If

End If
%>

L'archivio (chiamato lez08_iscritti.mdb) è così strutturato:

Un'unica tabella chiamata utenti, con 1 campo contatore (ID) e 3 campi testo (di 50 car).
Vediamo in modo particolare come avviene il controllo sul database.

E' necessario prima di tutto effettuare la connessione al database

'Connessione al database
  Set db = Server.CreateObject("ADODB.Connection")
  db.Open "provider=microsoft.jet.oledb.4.0;data source=" & Server.MapPath("lez08_iscritti.mdb")

Memorizziamo in due variabili l'username e la password presenti nel cookie

'Controllo dei dati inseriti nel modulo per il
  'riconoscimento con un database

  us = Request.Cookies("entra")("username")
  ps = Request.Cookies("entra")("password")

Attraverso una query SQL di selezione cerco nella tabella utenti se esiste un record che abbia i campi username e password come i valori prelevati dal cookie.

Set rsLogin = db.Execute("SELECT * FROM utenti WHERE UserName = '" & us & "' AND Password = '" & ps & "'")

Se non esistono (EOF = End Of File)

If rsLogin.EOF Then

Imposta la Sessione a False, ovvero l'utente non potrà accedere e sarà rimandato al modulo.

Session("permesso_entrata") = False
    Response.Redirect "lez08_modulo.asp?err=101"

  Else 

Imposta la Sessione a True, ovvero l'utente potrà accedere all'area riservata

Session("permesso_entrata") = True

  End If.

Autenticazione ibrida
Uno dei migliori sistemi di autenticazione è unire l'autenticazione Http a quella con il database. A volte capita di effettuare l'accesso ad un sito web utilizzare una finestra di dialogo di Windows che chiede l'inserimento di Username e Password che verranno criptati e se corrispondono ai dati di un utente Windows (registrato nel server) si avrà il permesse di accedere all'area riservata. Questo però è limitativo e permette un accesso esclusivamente ad amministratori e responsabili del sito.

Se si vuol utilizzare un sistema del genere per tutti gli utenti è necessario utilizzare questo sistema interfacciato ad un database.

Autenticazione di base
Vediamo i passaggi principali di questa autenticazione:

  1. Richiesta pagina protetta
  2. Il server risponde con il codice 401 Non Autorizzato
  3. Viene visualizzata una finestra di dialogo che chiede i dati di accesso
  4. Il browser invia i dati inseriti con un'intestazione chiamata AUTHORIZATION in modo criptato
  5. Il server decripta i dati passati e controlla se sono esatti
  6. Se corretti l'utente potrà accedere a tutte le pagine che richiedono il permesso (senza inserire ogni volta i dati).

Richiedere l'autenticazione di base
E' necessario innanzitutto controllare se l'intestazione AUTHORIZATION ha assegnato un valore, se non lo ha viene inviato il codice di stato 401 per far visualizzare una finestra di dialogo.

Codice 8.3

<%
'Memorizza intestazione AUTHORIZATION
autorizzazione = Request.ServerVariables("HTTP_AUTHORIZATION")

'Controllo, se è vuota accesso vietato
If Trim(autorizzazione) = "" Then
  'Imposta stato
  Response.Status = "401 Not Authorized"
  'Chiede di aprire finestra di dialogo per 
  'inserimento dati di acccesso
  Response.AddHeader "WWW-Authenticate", "Basic realm=""localhost"""
  Response.End
End If

'Se si viene riconosciuti, continua e visualizza l'intestazione.
%>
<html>
<head>
<title>Protezione area riservata - Lezione 8</title>
<body>
L'intestazione Authorization: <%=autorizzazione%>
</body>
</html>

I passaggi dell'intestazione AUTHORIZATION vengono tutti codificati nel metodo di codifica (abbastanza superato) base64, molto semplice, ma comunque valido, è tuttavia possibile utilizzare anche altri sistemi preferiti o software di terze parti.

Autenticazione ibrida
Vediamo ora il codice per effettuare un'autenticazione ibrida, ovvero l'auteticazione di base che controlla i dati di accesso in un database.

Codice 8.4

<%
autorizzazione = Request("HTTP_AUTHORIZATION")

'*******************************************************
'** www.webmasterpoint.org
'*******************************************************

'** INIZIO DECODIFICA
SET UUEncode = Server.CreateObject("Scripting.Dictionary")
For conta = 0 to 63
  Select CASE conta

    CASE 0 offset = 65
    CASE 26 offset = 71
    CASE 52 offset = -4

  End Select
  UUEncode( Chr(conta+offset)) = conta
Next

Function Decodifica(stringa)
  For codice = 1 to Len(stringa) Step 4
    numeroByte = 3
    gruppoByte = 0
    For ContaTesto = 0 to 3
      carattere = Mid(stringa, codice + ContaTesto,1)
      If carattere = "=" then
        numeroByte = numeroByte -1
        ByteAttuale = 0
      Else
        ByteAttuale = UUEncode(carattere)
      End If
      gruppoByte = 64 * gruppoByte + ByteAttuale
    Next

    For contaB = 1 To numeroByte
      Select CASE contaB

        CASE 1: carattere = gruppoByte  65536
        CASE 2: carattere = (gruppoByte AND 65535)  256
        CASE 3: carattere = (gruppoByte AND 255)

      End Select

      Decodifica = Decodifica & Chr(carattere)
    Next

  Next
End Function
'** FINE DECODIFICA

'Controllo, se è vuota accesso vietato
If Trim(autorizzazione) = "" Then

  Response.Status = "401 Not Authorized"
  Response.AddHeader "WWW-Authenticate", "Basic realm=""localhost"""
  Response.End

End If

autorizzazione= Trim(Mid(autorizzazione,6))
autorizzazione= Decodifica(autorizzazione)
autoDivisa = Split(autorizzazione, ":")
username = autoDivisa(0)
password = autoDivisa(1)
Response.Write(username)
Response.Write(password)
Response.End
'Connessione al database
Set db = Server.CreateObject("ADODB.Connection")
db.Open "provider=microsoft.jet.oledb.4.0;data source=" _
& Server.MapPath("lez08_iscritti.mdb")

Set rsLogin = db.Execute("SELECT * FROM utenti WHERE UserName = '" _
& username & "' AND Password = '" & password & "'")
If rsLogin.EOF Then

  Response.Status = "401 Not Authorized"
  Response.AddHeader "WWW-Authenticate", "Basic realm=""localhost"""
  Response.End

Else

 nomeUtente = RsLogin("nome")

End If

'Se si viene riconosciuti, continua e visualizza l'intestazione.
%>
<html>
<head>
<title>Protezione area riservata - Lezione 8</title>
<body>
Benvenuto <%=nomeUtente%>
</body>
</html>

Le righe di codice fino a '** INIZIO DECODIFICA permetto di effettuare la decodifica in base64, le restanti sono di semplice comprensione.

Viene effettuato un controllo se esiste un'intestazione AUTHORIZATION, se è vuota visualizza la finestra di dialogo, se è piena effettua la decodifica e controlla i dati nel database se sono esatti, se sono errati visualizza nuovamente la finestra di dialogo.

Tutto questo deve avvenire in una cartella che ha esclusivamente i permessi di Accesso Anonimo (Allow Anonymous Access).



Ti potrebbe interessare anche

commenta la notizia

C'è 1 commento
Francesco
Hai dubbi su questo articolo?