PHP ile HTTP Kimlik Doğrulaması

header() işlevi kullanılarak istemci tarayıcısına "Kimlik Doğrulaması Gerekli" ("Authentication Required") iletisini göndererilir ve bunun sonucunda Kullanıcı Adı/Parola giriş penceresi açılır. Kullanıcı kullanıcı adı ve parolasını girdiğinde, PHP betiğini içeren URL, kullanıcı adı, parola ve kimlik doğrulama türünü atayan PHP_AUTH_USER, PHP_AUTH_PW ve AUTH_TYPE öntanımlı değişkenleri ile tekrar çağrılır. Bu öntanımlı değişkenler $_SERVER dizileri içinde bulunur. Sadece "Temel" (Basic) ve "Özet" (Digest) kimlik doğrulama yöntemleri desteklenir. Daha fazla bilgi için header() işlevine bakınız.

İstemci sayfasını kimlik doğrulamaya zorlayacak örnek betik aşağıdaki gibidir:

Örnek 1 - Temel HTTP Kimlik Doğrulaması örneği

<?php
if (!isset($_SERVER['PHP_AUTH_USER'])) {
header('WWW-Authenticate: Basic realm="Benim bölgem"');
header('HTTP/1.0 401 Unauthorized');
echo
'Kullanıcı İptal düğmesine basınca çıkacak metin';
exit;
} else {
echo
"<p>Merhaba {$_SERVER['PHP_AUTH_USER']}.</p>";
echo
"<p>Parola olarak {$_SERVER['PHP_AUTH_PW']} verdiniz.</p>";
}
?>

Örnek 2 - Özet HTTP Kimlik Doğrulaması örneği

Bu örnek basit bir Özet HTTP kimlik doğrulama betiğinin nasıl uygulanacağını gösterir. Daha fazla bilgi için » RFC 2617 belgesini okuyunuz.

<?php
$saha
= 'Kısıtlanmış alan';

// kullanici => parola
$kullanicilar = array('yonetici' => 'gizlisifre', 'misafir' => 'misafir');


if (empty(
$_SERVER['PHP_AUTH_DIGEST'])) {
header('HTTP/1.1 401 Unauthorized');
header('WWW-Authenticate: Digest realm="'.$saha.
'",qop="auth",nonce="'.uniqid().'",opaque="'.md5($saha).'"');

die(
'Kullanıcı İptal düğmesine basınca çıkacak metin');
}


// PHP_AUTH_DIGEST değişkenini inceleyelim
if (!($veri = http_ozet_cozumle($_SERVER['PHP_AUTH_DIGEST'])) ||
!isset(
$kullanicilar[$veri['username']]))
die(
'Kimlik Doğrulama Hatası!');


// geçerli yanıt üretimi
$A1 = md5($veri['username'] . ':' . $saha . ':' .
$kullanicilar[$veri['username']]);
$A2 = md5($_SERVER['REQUEST_METHOD'].':'.$veri['uri']);
$gecerli_yanit = md5($A1.':'.$veri['nonce'].':'.$veri['nc'].':'.
$veri['cnonce'].':'.$veri['qop'].':'.$A2);

if (
$veri['response'] != $gecerli_yanit)
die(
'Kimlik Doğrulama Hatası!');

// tamam, geçerli kullanıcı adı & parolası
echo 'Hoşgeldiniz : ' . $veri['username'];


// http kimlik doğrulama başlığını çözümleyecek işlev
function http_ozet_cozumle($metin)
{
// eksik veriye karşı koruma
$gerekli_kisimlar = array('nonce'=>1, 'nc'=>1, 'cnonce'=>1, 'qop'=>1,
'username'=>1, 'uri'=>1, 'response'=>1);
$veri = array();
$keys = implode('|', array_keys($gerekli_kisimlar));


preg_match_all('@(' . $keys . ')=(?:([\'"])([^\2]+?)\2|([^\s,]+))@',
$metin, $eslesen, PREG_SET_ORDER);

foreach (
$eslesen as $m) {
$veri[$m[1]] = $m[3] ? $m[3] : $m[4];
unset(
$gerekli_kisimlar[$m[1]]);
}

return
$gerekli_kisimlar ? false : $veri;
}
?>

Bilginize: Uyumluluk Bilgisi

Lütfen HTTP başlık satırlarını kodlarken dikkatli olun. Bütün istemcilerle uyumluluğu garantilemek için, "Basic" anahtar sözcüğünün "B" harfi büyük yazılmalı, realm metni çift tırnak (tek tırnak değil) ile yazılmalı, ve HTTP/1.0 401 başlık satırındaki 401 kodundan önce tam olarak bir adet boşluk olmalıdır. Yukarıdaki özet örneğinde olduğu gibi kimlik doğrulama bağımsız değişkenleri virgülle ayrılmış olmalıdır.

Yukarıdaki örnekte yapıldığı gibi sadece PHP_AUTH_USER ve PHP_AUTH_PW yazdırmak yerine, kullanıcı adı ve parolasının doğruluğunu denetlemek isteyebilirsiniz. Bunun için belki bir veritabanı sorgusu gönderebilir veya kullanıcıyı bir dbm dosyası içinde arayabilirsiniz.

Burada hatalı Internet Explorer tarayıcılarına dikkat ediniz. Başlıkların sırası konusunda çok seçici görünürler. WWW-Authenticate başlığını HTTP/1.0 401 başlığından önce göndermek hileye neden olabilir.

Bilginize: Yapılandırma Bilgisi

PHP harici kimlik doğrulamasının etkin olup olmadığnı tespit etmek için AuthType yönergesininin varlığını bakar.

Yukarıdaki örnek, aynı sunucudaki kimlik doğrulamalı URL'lerden girilen parolaları çalmak için kimlik doğrulamasız bir URL'yi kullanmak isteyenleri önlemez.

Hem Netscape Navigator hem de Internet Explorer, 401 sunucu yanıtını almak için yerel tarayıcı penceresinin kimlik doğrulama önbelleğini temizler. Bu işlem, kullanıcıları tekrar kullanıcı adı ve parolasını girmeye zorlayacak şekilde "oturumu kapatır". Bazıları bunu "zaman aşımlı" kullanıcı girişi için kullanırlar veya bir "Çıkış" düğmesi sunarlar.

Örnek 3 - Yeni kullanıcı adı va parolası girmeye zorlayan bir HTTP kimlik doğrulama örneği

<?php
function authenticate() {
header('WWW-Authenticate: Basic realm="Kimlik Doğrulaması Deneme Sistemi"');
header('HTTP/1.0 401 Unauthorized');
echo
"Bu kaynağa erişmek için geçerli bir kullanıcı adı ve " .
"parolası girmelisiniz.\n";
exit;
}

if (!isset(
$_SERVER['PHP_AUTH_USER']) ||
(
$_POST['SeenBefore'] == 1 && $_POST['OldAuth'] == $_SERVER['PHP_AUTH_USER'])) {
authenticate();
} else {
echo
"<p>Merhaba: " . htmlspecialchars($_SERVER['PHP_AUTH_USER']) . "<br />";
echo
"Eski: " . 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='{$_SERVER['PHP_AUTH_USER']}' />\n";
echo
"<input type='submit' value='Kimliği Yeniden Doğrula />\n";
echo
"</form></p>\n";
}
?>

Bu davranış şekli HTTP Temel kimlik doğrulama standardı için gerekli değildir, bu nedenle buna güvenmemelisiniz. Lynx ile denendiğinde Lynx'in kimlik doğrulama kartlarını 401 sunucu yanıtı ile temizlemediğini göstermiştir, bu nedenle kimlik bilgisi değişmediği sürece geri ve ileri düğmesine basmak aynı kaynağı açacaktır. Kullanıcı '_' tuşu ile kimlik doğrulama bilgisini temizleyebilir.

HTTP kimlik doğrulamasının çalışması için IIS yapılandırmasındaki "Dizin Güvenliği"ni değiştirmelisiniz. "Düzenle"ye basınız ve sadece "Anonim Erişim"leri seçiniz, diğer bütün sahalar seçimsiz olmalıdır.

Bilginize: IIS Bilgisi:
HTTP kimlik doğrulamasının IIS ile çalışması için, PHP yönergesi cgi.rfc2616_headers değeri 0 olmaldır (öntanımlı değer).

To Top