Oleh : Abah Razi
بسم الله الرحمن الرحيم
Adalah dimungkinkan untuk menggunakan fungsi header
untuk mengirimkan suatu pesan “Authentication Required” ke browser klien yang memunculkan popup input username/password. Setelah pengguna mengisi username dan password, URL yang berisi script PHP akan dipanggil lagi dengan serangkaian predefined variable PHP_AUTH_USER
,PHP_AUTH_PW
dan AUTH_TYPE
untuk username, password dan tipe autentikasi. Variabel-variabel predefined ini didapati di array $_SERVER
dan <code?$HTTP_SERVER_VARS. Baik metode autentikasi “Basic” maupun “Digest” keduanya didukung (semenjak PHP 5.1.0). Lihat fungsi header()
untuk informasi lebih lanjut.
Catatan Versi PHP
Superglobal, seperti $_SERVER
ada semenjak PHP 4.1.0
Berikut contoh potongan scrip yang dapat memaksa autentikasi klien di halaman :
<?php if (!isset($_SERVER['PHP_AUTH_USER'])) { header('WWW-Authenticate: Basic realm="My Realm"'); header('HTTP/1.0 401 Unauthorized'); echo 'Text to send if user hits Cancel button'; exit; } else { echo "<p>Hello {$_SERVER['PHP_AUTH_USER']}.</p>"; echo "<p>You entered {$_SERVER['PHP_AUTH_PW']} as your password.</p>"; } ?>
Contoh 2 : Contoh Autentikasi HTTP Digest
Contoh berikut menunjukkan bagaimana mengimplementasikan script autentikasi HTTP Digest sederhana. Untuk informasi lebih lengkap silahkan rujuk 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'); } // analyze the PHP_AUTH_DIGEST variable if (!($data = http_digest_parse($_SERVER['PHP_AUTH_DIGEST'])) || !isset($users[$data['username']])) die('Wrong Credentials!'); // generate the valid response $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, valid username & password echo 'You are logged in as: ' . $data['username']; // function to parse the http auth header function http_digest_parse($txt) { // protect against missing data $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; } ?>
Catatan Kompatibilitas :
Berhati-hatilah saat mengkoding baris header HTTP. Untuk menjamin kompatibilitas maksimum ke seluruh klien, kata kunci “Basic” seharusnya diketik dengan huruf besar “B”, string realm mesti ditutup dengan tanda petik dua (bukan satu), dan hanya boleh ada satu spasi pada kode 401 di bari header HTTP/1.0 401
. Parameter-parameter autentikasi mestilah dipisahkan dengan koma seperti yang terlihat pada contoh diatas.
Alih-alih secara sederhana mengetikkan PHP_AUTH_USER
dan PHP_AUTH_PW
sebagaimana yang kita lakukan diatas, kita dapat juga mengecek username dan password untuk validitas. Misalnya dengan mengirimkan query ke database, atau dengan mengecek pengguna di sebuah file dbm.
Awas pula dengan buggy di Internet Explorer. Dia tampak sangat pilih-pilih terkait urutan header. Mengirimkan header WWW-Authenticate sebelum header HTTP/1.0 401 tampaknya dapat digunakan sebagai trik saat ini
Semenjak PHP 4.3.0, dalam rangka mencegah seseorang menulis suatu script yang dapat menemukan password sebuah halaman yang diautentikasi melalui mekanisme eksternal tradisional, variabel-variabel PHP_AUTH
tidak akan diset jika autentikasi eksternal diaktifkan untuk halaman tertentu dan safe mode dipasang. Bagaimanapun, REMOTE_USER
dapat digunakan untuk mengidentifikasi user yang diautentikasi secara eksternal, jadi kita dapat menggunakan $_SERVER['REMOTE_USER']
.
Catatan Konfigurasi
PHP menggunakan suatu direktif AuthType
untuk menentukan apakah autentikasi eksternal memberikan efek.
Perhatikan, bagaimapun, hal itu tidak mencegah seseorang yang mengendalikan suatu URL non-authenticated untuk mencuri password dari URL terautentikasi pada server yang sama.
Baik Netscape Navigator maupun Internet Explorer akan membersihkan jendela cache autentikasi browser lokal untuk realm saat menerima respon server 401. Hal ini dapat secara efektif me”log-out” pengguna, memaksa mereka untuk mengisikan ulang username dan password. Beberapa orang menggunakan ini untuk login “time out”, atau untuk menyediakan tombol “log-out”.
Contoh 3 Contoh Autentikasi HTTP memaksa sebuah nama/password baru
<?php function authenticate() { header('WWW-Authenticate: Basic realm="Test Authentication System"'); header('HTTP/1.0 401 Unauthorized'); echo "You must enter a valid login ID and password to access this resource\n"; exit; } if (!isset($_SERVER['PHP_AUTH_USER']) || ($_POST['SeenBefore'] == 1 && $_POST['OldAuth'] == $_SERVER['PHP_AUTH_USER'])) { authenticate(); } else { echo "<p>Welcome: " . htmlspecialchars($_SERVER['PHP_AUTH_USER']) . "<br />"; echo "Old: " . 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='Re Authenticate' />\n"; echo "</form></p>\n"; } ?>
Prilaku ini tidak dibutuhkan oleh standar autentikasi HTTP Basic, jadi kita seharusnya tidak pernah bergantung pada hal ini. Pengujian dengan Lynx telah menunjukkan bahwa Lynx tidak membersihkan kredensial autentikasi dengan respon server 401, sehingga menekan tombol “kembali” akan membukan kembali resource tersebut sepanjang kebutuhan kredensial tidak berubah. Pengguna dapat menekan tombol ‘_’ untuk membersihkan informasi autentikasi mereka.
Catat juga bahwa hingga PHP 4.3.3, autentikasi HTTP tidak bekerja menggunakan server IIS Microsoft dengan versi CGI PHP dikarenakan pembatasan di IIS. Untuk dapat membuatnya bekerja pada PHP 4.3.3+, kita mesti mengedit konfigurasi IIS “Directory Security”. Klik pada tombol “Edit” dan cukup berikan tanda pada “Anonymous Access”, sementara field yang lain sebaiknya dibiarkan tidak dicentang.
Limitasi yang lain adalah jika kita menggunakan modul IIS (ISAPI) dan PHP 4, kita tidak dapat menggunakan variabel PHP_AUTH_* tetapi dapat menggunakan variabel HTTP_AUTHORIZATION. Sebagai contoh perhatikan kode berikut
list($user, $pw) = explode(':', base64_decode(substr($_SERVER['HTTP_AUTHORIZATION'], 6)));
Catatan IIS
Agar autentikasi HTTP bekerja di IIS, direktif PHP headercgi.rfc2616_headers mesti diset bernilai 0 (nilai default)
Catatan
Jika safe mode diaktifkan, uid dari script ditambahkan ke bagian realm di header WWW-Authenticate
Leave a Reply