È possibile usare la
funzione header() per inviare un messaggio di "Authentication Required"
al browser dell'utente, provocando quindi l'apertura di una finestra contenente una richiesta di
Nome utente/Password. Una volta che l'utente ha compilato i campi nome utente e password,
l'URL contenente lo script PHP verrà richiamato nuovamente usando le
variabili predefinite,
PHP_AUTH_USER, PHP_AUTH_PW e
AUTH_TYPE impostate con nome, password e
tipo di autenticazione. Queste variabili predefinite possono essere trovate
nell'array $_SERVER. Saranno supportati entrambi i
metodi di autenticazione, "Basic" e "Digest" (a partire dal PHP 5.1.0).
Fare riferimento alla funzione header() per ulteriori informazioni.
Un frammento di script di esempio che richiede l'autenticazione da parte del browser su una pagina, potrebbe essere il seguente:
Example #1 Esempio di Autenticazione HTTP "Basic"
<?php
if (!isset($_SERVER['PHP_AUTH_USER'])) {
header('WWW-Authenticate: Basic realm="Il mio realm"');
header('HTTP/1.0 401 Unauthorized');
echo 'Messaggio da inviare se si preme il tasto Cancel';
exit;
} else {
echo "<p>Ciao {$_SERVER['PHP_AUTH_USER']}.</p>";
echo "<p>Hai inserito {$_SERVER['PHP_AUTH_PW']} come tua password.</p>";
}
?>
Example #2 Esempio di autenticazione HTTP "Digest"
Questo esempio illustra come implementare una autenticazione Digest. Per maggiori dettagli vedere » RFC 2617.
<?php
$realm = 'Restricted area';
//user => password
$users = array('admin' => 'mypass', 'guest' => 'guest');
if (empty($_SERVER['PHP_AUTH_DIGEST'])) {
header('HTTP/1.1 401 Unauthorized');
header('WWW-Authenticate: Digest realm="'.$realm.
'",qop="auth",nonce="'.uniqid().'",opaque="'.md5($realm).'"');
die('Text to send if user hits Cancel button');
}
// analisi della variabile PHP_AUTH_DIGEST
if (!($data = http_digest_parse($_SERVER['PHP_AUTH_DIGEST'])) ||
!isset($users[$data['username']]))
die('Wrong Credentials!');
// generazione di una risposta valida
$A1 = md5($data['username'] . ':' . $realm . ':' . $users[$data['username']]);
$A2 = md5($_SERVER['REQUEST_METHOD'].':'.$data['uri']);
$valid_response = md5($A1.':'.$data['nonce'].':'.$data['nc'].':'.$data['cnonce'].':'.$data['qop'].':'.$A2);
if ($data['response'] != $valid_response)
die('Wrong Credentials!');
// Ok, utente/password validi
echo 'Your are logged in as: ' . $digest['username'];
// funzione che analizza l'header http auth
function http_digest_parse($txt)
{
// protezione contro i dati mancanti
$needed_parts = array('nonce'=>1, 'nc'=>1, 'cnonce'=>1, 'qop'=>1, 'username'=>1, 'uri'=>1, 'response'=>1);
$data = array();
$keys = implode('|', array_keys($needed_parts));
preg_match_all('@(' . $keys . ')=(?:([\'"])([^\2]+?)\2|([^\s,]+))@', $txt, $matches, PREG_SET_ORDER);
foreach ($matches as $m) {
$data[$m[1]] = $m[3] ? $m[3] : $m[4];
unset($needed_parts[$m[1]]);
}
return $needed_parts ? false : $data;
}
?>
Nota: Note sulla compatibilità
Fare molta attenzione quando si scrive codice per le intestazioni HTTP. Per ottenere la massima compatibilità con tutti i client, la parola-chiave "Basic" deve essere scritta con una "B" maiuscola, la stringa realm deve essere racchiusa in virgolette doppie (non singole), ed esattamente uno spazio deve precedere il codice 401 nella linea di intestazione HTTP/1.0 401. I parametri di autenticazione devono essere separati da virgole come si vede nell'esempio qui sopra.
Invece di stampare semplicemente PHP_AUTH_USER e PHP_AUTH_PW, probabilmente si vorrà controllare la validità dello username e della password. Probabilmente inviando una chiamata al database, o cercando un utente in un file dbm.
Si faccia attenzione ad alcune versioni di Internet Explorer. Sembra
che siano molto schizzinosi riguardo all'ordine delle intestazioni. Inviare l'intestazione
WWW-Authenticate prima dell'intestazione
HTTP/1.0 401
sembra sistemare le cose per
il momento.
Nota: Nota sulla Configurazione
PHP usa la presenza di una direttiva
AuthType
per determinare se viene utilizzata l'autenticazione esterna.
Si fa notare, però, che quanto scritto sopra non impedisce a qualcuno che controlla un URL non autenticato di sottrarre password da URL autenticati presenti sullo stesso server.
Sia Netscape Navigator che Internet Explorer cancellano la cache locale della finestra del browser, per quanto riguarda il realm, al ricevimento di una risposta 401 da parte del server. Questo è effettivamente un meccanismo di "log out" per l'utente, che lo forza a reinserire lo username e la password. Alcune persone usano questo per fare il "time out" dei login, o per rendere disponibili bottoni di "log-out".
Example #3 Esempio di Autenticazione HTTP che impone l'inserimento di nuovo username/password
<?php
function authenticate() {
header('WWW-Authenticate: Basic realm="Prova del Sistema di Autenticazione"');
header('HTTP/1.0 401 Unauthorized');
echo "Per poter accedere a questa risorsa occorre inserire una coppia login e password valide\n";
exit;
}
if (!isset($_SERVER['PHP_AUTH_USER']) ||
($_POST['SeenBefore'] == 1 && $_POST['OldAuth'] == $_SERVER['PHP_AUTH_USER'])) {
authenticate();
} else {
echo "<p>Benvenuto: " . htmlspecialchars($_SERVER['PHP_AUTH_USER']) . "<br />";
echo "Vecchio: " . htmlspecialchars($_REQUEST['OldAuth']);
echo "<form action='' method='post'>\n";
echo "<input type='hidden' name='SeenBefore' value='1' />\n";
echo "<input type='hidden' name='OldAuth' value=\"" . htmlspecialchars($_SERVER['PHP_AUTH_USER']) . "\" />\n";
echo "<input type='submit' value='Ri autentifica' />\n";
echo "</form></p>\n";
}
?>
Questo comportamento non è richiesto dallo standard di autenticazione HTTP
Basic, quindi non si dovrebbe mai fare affidamento su di esso. Test effettuati con
Lynx
mostrano che Lynx
non cancella
le credenziali di autenticazione al ricevimento del codice di risposta 401 da parte del server, quindi, premendo indietro
e avanti nuovamente, darà nuovamente accesso alla risorsa, ammesso che le rispettive richieste
di credenziali non siano cambiate. L'utente può però premere il
tasto '_' al fine di cancellare le sue informazioni di autenticazione.
Al fine di far funzionare l'Autenticazione HTTP usando il server IIS con la versione CGI
di PHP si deve modificare la configurazione di IIS "Directory Security
".
Cliccare su "Edit
" e selezionare solo
"Anonymous Access
", tutti gli altri campi
devono essere lasciati deselezionati.
Nota: Nota su IIS:
Al fine di fare funzionare la Autenticazione HTTP con IIS, la direttiva PHP cgi.rfc2616_headers deve essere impostata al valore0
(il valore predefinito).