PHP K�sikirja
Edellinen |  | Seuraava

# Luku 34. PHP ja HTTP-autentikaatio

PHP:n HTTP-autentikaatiotuki on käytettävissä ainoastaan mikäli PHP on asennettu Apachen moduuliksi, eikä siten ole saatavilla CGI-moduulissa. Apachen moduulina ajettavassa PHP-skriptissä voidaan header() -funktiolla lähettää Web-selaimelle autentikaatiopyyntö, jolloin toteutustavasta riippuen selain kysyy käyttäjältä käyttäjätunnusta ja salasanaa. Kun käyttäjä on saanut syötettyä nämä tiedot, URL:ia, jossa tämä skripti sijaitsee, kutsutaan uudelleen. Tällä kertaa ennalta määriteltyjen muuttujien PHP_AUTH_USER, PHP_AUTH_PW ja AUTH_TYPE arvoina on käyttäjän syöttämät tiedot sekä autentikaatiotyyppi. Nämä muuttujat löytyvät $_SERVER ja $HTTP_SERVER_VARS -listoista. Vain yksinkertainen (Basic) autentikaatio on tuettu. Lisätietoja asiasta löytyy funktiosta header().

> PHP:n versioista: Superglobaalit, kuten $_SERVER tulivat käyttöön PHP:n versiossa 4.1.0. $HTTP_SERVER_VARS on ollut käytössä PHP 3:sta lähtien.

Seuraavanlaisella skriptinpätkällä voidaan pakottaa asiakas tunnistautumaan sivulle.

Esimerkki 34-1. HTTP-autentikaatioesimerkki

`<?php if (!isset($_SERVER['PHP_AUTH_USER'])) { header('WWW-Authenticate: Basic realm="Suojattu alue"'); header('HTTP/1.0 401 Unauthorized'); echo 'Tämä teksti näytetään käyttäjälle mikäli hän hylkää ' . 'autentikaatiopyynnön.'; exit; } else { echo "<p>Päivää, {$_SERVER['PHP_AUTH_USER']}.</p>"; echo "<p>Syötit salasanan {$_SERVER['PHP_AUTH_PW']}.</p>"; } ?>`

> Huomautus yhteensopivuudesta: Muista kiinnittää huomiota HTTP-otsikkotietojen kirjoitusasuun! Taataksesi mahdollisimman hyvän yhteensopivuuden eri selainten kanssa, huomaa että avainsana "Basic" tulee kirjoittaa isolla alkukirjaimella "B", realm-attribuutin arvon tulee olla lainausmerkeissä (ei heittomerkein eroteltuna) ja otsikkorivin HTTP/1.0 401 koodinumeroa 401 ennen tulee olla tasan yksi välilyönti.

Pelkän syötettyjen arvojen tulostamisen sijaan voit mahdollisesti haluta tarkistaa muuttujien PHP_AUTH_USER ja PHP_AUTH_PW sisällön oikeellisuuden, ehkäpä tekemällä kyselyn tietokantaan tai etsimällä käyttäjää dbm-tiedostosta.

Varo virheellisesti toimivia Internet Explorerin versioita. Ne saattavat olla erittäin tarkkoja siitä missä järjestyksessä HTTP-otsikkotiedot syötetään. WWW-Authenticate -otsikon lähettäminen ennen HTTP/1.0 401 -otsikkoa näyttäisi kuitenkin toimivan tällä hetkellä.

PHP 4.3.0 ja uudemmat versiot eivät aseta PHP_AUTH-muuttujia, mikäli ulkoinen autentikaatio on otettu käyttöön määritetyllä sivulla ja mikäli safe mode on käytössä. Tämä estää sellaisten skriptien teon, joilla voitaisiin paljastaa perinteisin metodein autentikoidun käyttäjän tunnukset. Siitä huolimatta, REMOTE_USER -muuttujaa (eli $_SERVER['REMOTE_USER']) voidaan käyttää ulkoisesti autentikoidun käyttäjän tunnistamiseen.

> Huomaa konfiguroidessa: PHP määrittää asetuksen AuthType olemassaolon perusteella sen, onko ulkoinen autentikaatio käytössä.

Huomaa kuitenkin, että edellämainittu tapa ei estä samalla palvelimella sijaitsevia ei-autentikoituja URLeja varastamasta autentikoidun URLin salasanoja.

Sekä Netscape Navigator että Internet Explorer tyhjentävät HTTP-autentikaatiotiedot välimuististaan saadessaan HTTP-vastauksen 401. Tällä keinolla voidaan "kirjata ulos" käyttäjä, pakottaen heidät syöttämään käyttäjätunnuksensa uudelleen. Jotkut käyttävät tätä keinoa istuntojen aikakatkaisuun tai "kirjaudu ulos" -painikkeen toteuttamiseen.

Esimerkki 34-2. Esimerkki uudelleenautentikoitumisen pakottamisesta

`<?php
function authenticate() {
header('WWW-Authenticate: Basic realm="Testijärjestelmä"');
header('HTTP/1.0 401 Unauthorized');
echo "Syötä käyttäjätunnus ja salasana käyttääksesi tätä resurssia.\n";
exit;
}
if (!isset($_SERVER['PHP_AUTH_USER']) ||
($_POST['SeenBefore'] == 1 && $_POST['OldAuth'] == $_SERVER['PHP_AUTH_USER'])) {
authenticate();
}
else {
echo "<p>Tervetuloa: {$_SERVER['PHP_AUTH_USER']}<br />";
echo "Vanha: {$_REQUEST['OldAuth']}";
echo "<form action='{$_SERVER['PHP_SELF']}' METHOD='post'>\n";
echo "<input type='hidden' name='SeenBefore' value='1' />\n";
echo "<input type='hidden' name='OldAuth' value='{$_SERVER['PHP_AUTH_USER']}' />\n";
echo "<input type='submit' value='Vaihda käyttäjää' />\n";
echo "</form></p>\n";
}
?>`

Tämänkaltaista toiminnallisuutta ei kuitenkaan vaadita HTTP Basic authentication -standardissa, joten siihen ei tulisi koskaan luottaa. Testaaminen Lynx-selaimella osoittaa, että Lynx ei tyhjennä autentikaatiotietojaan saadessaan palvelimelta vastauksen 401, joten palaaminen edelliselle sivulle ja samantien takaisin avaa uudelleen saman resurssin -- niin kauan kuin käyttöoikeusvaatimukset eivät ole muuttuneet. Käyttäjä voi kuitenkin painaa Lynxissä '_' -näppäintä tyhjentääkseen autentikaatiotiedot.

Huomaa myös, että HTTP-autentikaatio ei ole toiminut ennen PHP:n versiota 4.3.3 CGI-moduulina Microsoftin IIS-palvelimessa sen rajoittuneisuuden takia. Sen käyttöönotto PHP 4.3.3:ssa tai uudemmissa versioissa vaatii asetuksen "Directory Security" muokkausta. Klikkaa kohtaa "Edit" ja valitse ainoastaan "Anonymous Access", kaikki muut kentät tulee jättää tyhjäksi.

PHP:n IIS-moduulissa (ISAPI) on puolestaan sellainen puute, että PHP_AUTH_* muuttujia ei voida käyttää, vaan niiden sijaan on käytettävä muuttujaa HTTP_AUTHORIZATION. Kokeile esimerkiksi seuraavaa koodia: list($user, $pw) = explode(':', base64_decode(substr($_SERVER['HTTP_AUTHORIZATION'], 6)));.

> Huomautus IIS:n käyttäjille: Jotta HTTP-autentikaatio toimisi IIS-palvelimen kanssa, cgi.rfc2616_headers-asetuksen arvon tulee olla 0, joka on myös asetuksen oletusarvo.

> Huomaa: Mikäli safe mode on käytössä, ajettavan skriptin UID lisätään WWW-Authenticate-otsikon realm-attribuutin arvoon.

Edellinen | Alkuun | Seuraava
Ominaisuudet | Ylös | Evästeet