Lezione Precedente
Lezione Successiva

Laboratorio di Sistemi Informativi

Accesso privilegiato e autenticazone

In un sistema vero è plausibile che l'accesso alle funzioni di di interrogazione sia libero. Nel nostro caso, tutti devono poter interrogare la base di dati per sapere quali sono i voli disponibili. Tuttavia, le funzioni di di modifica della base di dati devono essere protette, in modo tale che soltanto le persone autorizzate possano utilizzarle. Occorre quindi prevedere un sistema per l'autenticazione degli utenti. Anche se il server SQL dispone di un meccanismo di controllo dei diritti di accesso, di solito non è conveniente utilizzare direttamente questo sistema. I diritti a livello di server SQL vegono concessi dall'amministratore del database alle diverse figure che su di esso operano (il progettista, lo sviluppatore delle applicazioni, il gruppo di testing). Di solito, ad una applicazione viene associato un unico utente (o anche di più, ma comunque in numero limitato) per effettuare le connessioni al DBMS. Se l'applicazione, al suo interno, ha bisogno di distinguere tra diversi utilizzatori, è meglio che sia lei stessa ad autenticarli, in modo da non congestionare il sistema di gestione utenti del DBMS.

Per questo motivo, inseriamo un nuova tabella nel database airdb, la tabella utenti, che contiene un elenco di username e password di persone che hanno diritto all'accesso in modifica ai dati. Ovviamente, in un sistema vero, persone diverse hanno diritti diversi, ma nel nostro caso supponiamo che esista una sola grande categoria di utenti privilegiati. Questi sono i comandi per creare la nuova tabella e riempirla con un paio di utente fittizi:

CREATE TABLE utenti (
   username char(10) primary key,
   passwd char(40)
);

INSERT INTO utenti VALUES ('ut1',SHA1('ut1'));
INSERT INTO utenti VALUES ('prova',SHA1('pwd'));


Notare l'uso della funzione intrinseca SHA1 che serve a criptare una stringa. Quando si memorizzano delle password, è sempre bene memorizzarle criptate, in modo che anche se qualcuno non autorizzato riuscisse ad accedere alla tabella utenti, non riuscirebbe comunque a risalire da questa alle password dei vari utenti.

In realtà, la funzione SHA1 non esegue veramente una cifratura della password, ma ne calcola una firma: una valore binario di 160 bit che è rappresentato come stringa di 40 caratteri esadecimali. La differenza sta nel fatto che, quando si parla di cifratura, si suppone che sia possibile, dal dato cifrare, risalire al dato originario, conoscendo una qualche chiave di decodifica. Nel caso della funzione SHA1 questo non è possibile, perchè stringhe diverse possono dare origine alla stessa firma.

A questo punto, se vogliamo che gli inserimenti siano riservati al personale autorizzato, possiamo fare in modo da richiedere login e password nella stessa pagina in cui chiediamo i dati per il nuovo volo. Ad esempio, consideriamo il file inserimento-pwd.php che contiene, in un unico file, gli script per l'inserimento dati visti precedentemente, aggiornati con il trattamento delle password.

La differenza fondamentale rispetto alla procedura di inserimento vista nelle lezioni scorse è che, nella parte relativa all'inserimento vero e proprio, prima di procedere si controlla se la username e password immessi corrispondono a quelle presenti nella tabella utenti. Si noti a questo proposito che anche PHP ha una funzione di nome sha1, come MySQL, che da esattamente gli stessi risultati. Per controllare se le credenziali inserite sono corrette, si calcola prima di tutto la firma della password, e poi si controlla se, nella tabella utenti, è presente una riga che ha la stessa username e la stessa firma della password immessa dall'utente. Se questa riga esiste si esegue l'inserimento normalmente, altrimenti ci si ferma con un messaggio di errore, con il quale si indica che l'utente non ha i diritti necessari per inserire il nuovo volo. Ecco lo spezzone di codice PHP corrispondente a questo controllo:

$hashedpwd=sha1($_POST['passwd']);
$result=mysql_query("select * from utenti where username='$_POST[user]' ".
                    "and passwd='$hashedpwd'") or mysql_showerror();
if (mysql_num_rows($result)==0)
  die ("Errore! non hai i diritti di inserire i dati");
In alternativa, si poteva far eseguire l'operazione di calcolo della firma direttamente a MySQL, scrivendo una cosa di questo tipo:

$result=mysql_query("select * from utenti where username='$_POST[user]' ".
                    "and passwd=sha1('$_POST[passwd]')") or mysql_showerror();
if (mysql_num_rows($result)==0)
  die ("Errore! non hai i diritti di inserire i dati");
Il vantaggio della nostra soluzione è che la password non viene inviata in chiaro dal PHP al MySQL, cosa che in certe situazioni potrebbe costituire un problema per la sicurezza del sistema.

Sessioni e autenticazione

Ovviamente questo tipo di interfaccia è molto scomoda. Ogni volta che inseriamo un nuovo volo bisogna fornire login e password. Sarebbe molto più comodo avere una pagina di login iniziale per autenticare l'utente una volta per tutte. La corretta autenticazione da il diritto di accedere alle funzioni riservate di modifica della base di dati. Questo è possibile con l'uso delle sessioni.

La prima cosa da fare è realizzare una pagina per il login all'area protetta: login.php. Quando lo script viene richiamato senza parametri, visualizza una form per la richiesta di username e password. Premendo il pulsante "Login" lo script viene eseguito con i parametri user e password che assumono i valori previsti dall'utente. A questo punto lo script controlla sulla tabella utenti del database airdb se le informazioni sono valide e nel caso redirige il browser alla pagina menu.php. In caso di login corretto viene anche assegnato il valore true alla variabile di sessione "user".

La pagina menu.php visualizza un menù con le opzioni possibili nella modalità privilegiata. Notare che, prima di tutto, viene effettuato un controllo sulla variabile $_SESSION['user']. Se questa è settata a true, vuol dire che all'utente è stata concessa l'autorizzazione dalla procedura di login, e quindi autorizzato a proseguire. Altrimenti, l'utente sta tentando di accedere a questa pagina senza prima essersi autenticato, per cui viene rediretto automaticamente alla pagina login.php.

La pagina logout.php utilizza la funzione session_destroy() per cancellare la sessione corrente. Da quel punto in poi, l'utente deve rieffettuare il login per essere ammesso alle funzioni privilegiate.

Infine, abbiamo la sezione che riguarda l'inserimento di nuovi voli che non presenta rilevanti novità rispetto a quella vista all'inizio della lezione. Il codice di inserimento-session.php è molto simile a quello di inserimento-pwd.php, con la differenza che all'inizio del file si controlla se l'utente è autorizzato ad accedere alle funzioni di inserimento, controllando se la variabile $_SESSION['user'] è definita oppure no.

Notare che, per controllare se l'utente è autorizzato, è possibile o controllare che $_SESSION['user'] sia uguale a true (come fatto in menu.php) o semplicemente che gli sia stato assegnato un valore (come fatto in inserimento-session.php). In questo caso, entrambe le soluzioni vanno bene.

Esercizio 

Modificare gli script login.php e menu.php in modo che prima del menù venga visualizzato un messaggio del tipo "Benvenuto utente xyz" dove al posto di xyz va inserita la username utilizzata dall'utente durante l'autenticazione.

Lezione Precedente
Lezione Successiva

I file utilizzati in questa lezione: airdb2.sql, error.php, e .htaccess