Autenticazione dell'utente per accesso in area riservata

L'autenticazione è il procedimento di accertamento dell'identità di un utente che chiede un servizio.

Le pagine web dinamiche che effettuano operazioni di modifica (INSERT, UPDATE e DELETE) sono potenzialmente pericolose perchè tramite queste si potrebbero arrecare danni alla banca dati. Anche una semplice query di selezione potrebbe fornire informazioni riservate a chi non è l'interessato.

In alcuni casi è inevitabile consentire l'accesso a queste pagine a visitatori non autenticati come ad esempio per registrarsi in un "libro dei visitatori" ma nella maggior parte dei casi le pagine che modificano i contenuti della banca dati devono essere protette da un procedimento di autenticazione con un duplice obiettivo: filtrare i dati di interesse per l'utente e individuare chi sta operando. Un sistema di autenticazione serve anche per la semplice consultazione di dati sensibili o riservati quali potrebbero essere, ad esempio, i voti e le assenze degli studenti.


Il processo di autenticazione consiste di tre fasi:

  1. dati di identificazione:
    il servizio richiede all'utente di farsi identificare - l'utente fornisce tutti i dati che consentono il suo riconoscimento. In questa fase l'utente riceve sul suo browser la richiesta di fornire la coppia di dati username e password. L'utente compila i campi e spedisce i dati al server.
  2. accertamento e selezione:
    il servizio procede al riconoscimento dell'utente verificando che i dati di identificazione ottenuti corrispondano ad un utente autorizzato ad accedere all'area riservata. Se l'utente non è riconosciuto il server ripropone l'immissione dei dati di identificazione, altrimenti consente all'utente di proseguire.
  3. mantenimento dello stato di autenticazione:
    il servizio adotta degli accorgimenti per mantenere valida l'autenticazione per un determinato tempo, affinchè nel passare da una pagina ad un'altra della sezione riservata, non sia necessario costringere l'utente a ripetere la fase di autenticazione.

Il servizio viene concesso se tutte le fasi vengono superate, viceversa il fallimento di una qualunque di queste comporta il rifiuto.

In generale le applicazioni web sono realizzate da più di una pagina e non è sufficiente che sia sottoposta ad autenticazione solo la prima pagina, altrimenti conoscendo l'indirizzo delle pagine successive vi si potrebbe accedere direttamente aggirando la protezione. È necessario dunque che tutte le pagine che sono in "area riservata" siano sottoposte ad autenticazione.

Sarebbe molto scomodo riproporre, per ogni pagina, la fase di immissione dei dati di identificazione: diventerebbe un fastidio eccessivo per l'utente.

Pertanto gli "accorgimenti" adottati per mantenere lo stato di "autenticato" devono consentire all'utente, una volta che abbia superato la prima autenticazione, di utilizzare nel seguito tutte le pagine dell'area riservata.

La "sessione di lavoro autenticato" è il periodo di tempo in cui resta valida l'autorizzazione ad accedere all'area riservata, a partire dall'autenticazione (apertura della sessione o login) fino al termine (chiusura di sessione o logout).


Vengono presentati tre metodi di autenticazione:

  1. Autenticazione "Basic" del protocollo HTTP
  2. Autenticazione di "sessione" di PHP
  3. Autenticazione di "sessione" di PHP combinata con protocollo "IMAP"

Esempi dimostrativi senza banca dati

In questi semplici esempi le informazioni di autenticazione (nome utente e password non cifrata) sono contenute nello script stesso. Questa tecnica non è accettabile in una vera applicazione web per due motivi:

  1. la manutenzione dei dati (aggiunta, eliminazione, …) richiede un intervento sullo script;
  2. la segretezza delle informazioni non è garantita in modo adeguato.

In genere i dati di autenticazione sono contenuti, in forma cifrata, in una banca dati gestita dal server sql. Una soluzione intermedia è l'archiviazione dei dati cifrati in un file. Questo file si può trovare all'esterno della directory radice del web ed avere diritti di accesso limitati ottenendo in questo modo una sicurezza ragionevole ma la comodità di manutenzione è sicuramente inferiore ad una gestione con banca dati.

Autenticazione "Basic" del protocollo HTTP

È il metodo più semplice, ma ragionevolmente efficace. La procedura di autenticazione è quasi completamente affidata al server web usando quindi risorse standard del protocollo HTTP.

Si ottiene uno script semplice che può essere trasformato in un file e, tramite una direttiva di inclusione, inserito in tutte le pagine protette. In questo modo le pagine sono totalmente ignare della presenza del sistema di autenticazione.

Non è implementato da tutti i server web, ad esempio non può essere utilizzato con IIS mentre funziona con APACHE.

La pagina inviata al client deve essere preceduta da un "header" (campo del pacchetto HTTP) che obblighi l'utente ad autenticarsi per ottenere l'accesso alla pagina.

L'autenticazione si basa sull'esistenza di due variabili di ambiente che l'interprete PHP passa alla pagina quando entra in esecuzione. Sono due elementi dell'array associativo $_SERVER:

Quando un utente, cliccando su un link o scrivendo l'indirizzo nella casella dell'indirizzo del browser, invia una richiesta http (GET) che corrisponde all'accesso per la prima volta, dall'inizio della sessione, ad un'area riservata, il server web, non trovando alcun valore nelle due variabili di ambiente anzichè mandare al browser la pagina richiesta invia una richiesta di autenticazione che viene presentata come un form contenente:

La risposta che segue l'autenticazione contiene anche il testo da presentare in caso di mancato riconoscimento (non la vera pagina) ma il browser non mostra queste informazioni perchè è sospeso in attesa dell'inserimento dei dati.

La conferma dei dati da parte dell'utente produce una nuova richiesta http (GET) in cui, questa volta, c'è anche il campo "credentials" cifrato con codice "base64" contenente nome utente e password; la pagina dinamica viene quindi rilanciata ma questa volta le due variabili di ambiente posseggono un valore e lo script può verificarne la validità.

Se la coppia nomeutente/password è corretta si passa all'esecuzione della pagina vera e propria. Il browser memorizza le "credentials" e le ripropone anche per tutte le altre pagine che vengono visitate nella stessa sessione di lavoro per una specifica "area di autenticazione". In questo modo dopo una prima autenticazione, la visita di altre pagine che richiedono l'autenticazione per la stessa area, non produce ulteriori richieste di autenticazione cioè lo script trovando che le variabili di ambiente sono state convalidate non invia più l'header di autenticazione.

Non esiste un metodo di logout: per rimuovere le "credentials" (e quindi l'autenticazione) si deve chiudere il browser.

Se la coppia nomeutente/password è sbagliata lo script ripete la richiesta di autenticazione e il browser riapre il riquadro di richiesta dati di autenticazione.

Dopo tre fallimenti consecutivi il browser abbandona il tentativo e mostra il testo da presentare in caso di mancato riconoscimento dell'utente. Per fare un nuovo tentativo si deve ricaricare la pagina.

Se il visitatore annulla il form le variabili non vengono inizializzate e il browser abbandona subito, senza ulteriori tentativi, mostrando il testo da presentare in caso di fallimento. Per fare un nuovo tentativo si deve ricaricare la pagina.

L'inserimento dell'header nella pagina viene effettuato da uno script php che usa la funzione intrinseca header che inserisce un header HTTP in una pagina:

 

header( "WWW-authenticate: basic realm=\"area di autenticazione\"");

 

La stringa "area di autenticazione" può essere sostituita da una stringa significativa per descrivere il motivo dell'autenticazione.

Questa funzione deve essere la prima riga della pagina inviata dal server al browser perchè l'header, essendo l'intestazione del pacchetto http, deve essere inviato prima di ogni altro tag html.

Lo script php, che viene rilanciato ad ogni richiesta del browser, verifica se la variabile di ambiente $_SERVER['PHP_AUTH_USER'] esiste. Se non esiste, lo script genera un header di richiesta di autenticazione seguito dalle istruzioni per un corretto login.

Una funzione exit() o die() nello script garantisce che la pagina che segue possa essere mostrata. Progettando in questo modo non strutturato è più facile realizzare un file di inclusione che rende le pagine totalmente indipendenti dal meccanismo di autenticazione.

Se $_SERVER['PHP_AUTH_USER'] esiste si passa alla fase di verifica della accettabilità.

Se la verifica fallisce si termina come nel caso precedente.

Se la verifica ha successo si prosegue con la generazione della pagina che segue il file di inclusione (sessione attivata).

In questo semplice esempio dimostrativo la verifica di accettabilità si basa su un confronto dei dati inseriti dall'utente con dati contenuti in un array associativo interno allo script

nome del file: autenticami.php

 <?php

1:   $utenti = array('user1' => 'abcdef','user2' => 'ghijkl');

2:   if(!isset($_SERVER['PHP_AUTH_USER'])) {

3      header( "WWW-authenticate: basic realm=\"area di autenticazione\"");

4:     header( "HTTP/1.0 401 Unauthorized");

6:     die();

     } else {

7:     if (!isset($utenti[$_SERVER['PHP_AUTH_USER']])) {

8:       header( "WWW-authenticate: basic realm=\"area di autenticazione\"");

9:       header('HTTP/1.1 401 Unauthorized');

11:      die();

       }

12:    if ($utenti[$_SERVER['PHP_AUTH_USER']] != $_SERVER['PHP_AUTH_PW']){

13:      header( "WWW-authenticate: basic realm=\"area di autenticazione\"");

14:      header('HTTP/1.1 401 Unauthorized');

15:     die();

       }

    }

 ?>

 ...

Commenti:

1Lo script, che può essere staccato dalla pagina ed inserito in un file di inclusione, inizia definendo l'array associativo $utenti in cui le chiavi sono i nomi utenti accettabili (user1 e user2) e i valori sono le loro password in chiaro (abcdef e ghijk).
2Se la variabile di ambiente relativa al nome utente non è definita (prima richiesta)
3-5lo script invia al browser l'intestazione di autenticazione, elenca le istruzioni di login e termina (die()).
l'header HTTP/1.1 401 viene inviato al client per cancellare eventuali valori già presenti nelle caselle "Utente" e "password"
7Se le variabili di ambiente sono definite (lanci successivi) verifica se esiste la chiave relativa al nome utente nell'array associativo $utenti. Se non esiste risponde con una intestazione di autenticazione, propone le istruzioni di login e termina (die()).
12Se esiste la chiave relativa al nome utente nell'array associativo verifica se la password corrisponde. Se non corrisponde risponde con una intestazione di autenticazione, propone le istruzioni di login e termina (die()). Le password sono in chiaro perchè sebbene siano trasferite in cifra vengono decifrate dal protocollo HTTP.

Se tutti i controlli sono stati superati l'include termina senza chiusure premature e quindi si passa all'esecuzione dello script vero e proprio.

D'ora in poi (ultima fase) l'accesso a qualsiasi pagina della stessa "area di autenticazione" procede senza ulteriori richieste all'utente perchè le due variabili di ambiente sono impostate nel browser che le manda insieme ad ogni richiesta.

La pagina di autenticazione può essere inclusa in ciascuna pagina della sezione riservata. Ad esempio, La seguente pagina richiama prima lo script autenticami.php e, se questo non viene fermato con die(), continua a mostrare il resto della pagina.

nome file: Riservata.php

<?php

include('autenticami.php');

?>

<html>

<body>

Qui inizia la sezione autenticata:<br>

Ciao <?php echo $_SERVER['PHP_AUTH_USER'] ?>

<br>vai a questo <a href="areaRiservata.php">link</a>

per verificare che sarai autenticato automaticamente.

</body>

</html>

Il seguente script simula una seconda pagina dell'area protetta, per verificare che non è più richiesta l'autenticazione.

nome del file: areaRiservata.php

<?php

include('autenticami.php');

?>

<html><body>

Ciao <?php echo $_SERVER['PHP_AUTH_USER'] ?>

<br>Sei arrivato qui perchè ti sei autenticato.

<br>Se chiudi il browser, poi lo riapri e tenti di accedere a questa

pagina senza esserti autenticato, ti verrà chiesto

di inserire nome e password. Prova.

</body></html>