1<?php2/**3* DooDigestAuth class file.4*5* @author Leng Sheng Hong <darkredz@Gmail.com>6* @link http://www.doophp.com/7* @copyright Copyright © 2009 Leng Sheng Hong8* @license http://www.doophp.com/license9*/1011/**12* Handles HTTP digest authentication13*14* <p>HTTP digest authentication can be used with the URI router.15* HTTP digest is much more recommended over the use of HTTP Basic auth which doesn'tPRovide any encryption.16* If you are running PHP on Apache in CGI/FastCGI mode, you would need to17* add the following line to your .htaccessfor digest auth to work correctly.</p>18* <code>RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization},L]</code>19*20* <p>This class is tested under Apache 2.2 and Cherokee web server. It should work in both mod_php and cgi mode.</p>21*22* @author Leng Sheng Hong <darkredz@gmail.com>23* @version $Id: DooDigestAuth.php 1000 2009-07-7 18:27:2224* @package doo.auth25* @since 1.026*/27classDooDigestAuth{2829/**30* Authenticate against a list of username and passWords.31*32* <p>HTTP Digest Authentication doesn't work with PHP in CGI mode,33* you have to add this into your .htaccess <code>RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization},L]</code></p>34*35* @param string $realm Name of the authenticationsession36* @param array $users An assoc array of username and password: array('uname1'=>'pwd1', 'uname2'=>'pwd2')37* @param string $fail_msg Message to be displayed if the User cancel the login38* @param string $fail_url URL to be redirect if the User cancel the login39* @return string The username if login success.40*/41publicstaticfunctionhttp_auth($realm,$users,$fail_msg=NULL,$fail_url=NULL){42$realm= "Restricted area -$realm";4344//user => password45//$users = array('admin' => '1234', 'guest' => 'guest');46if(!empty($_SERVER['REDIRECT_HTTP_AUTHORIZATION']) &&strpos($_SERVER['REDIRECT_HTTP_AUTHORIZATION'], 'Digest')===0){47$_SERVER['PHP_AUTH_DIGEST'] =$_SERVER['REDIRECT_HTTP_AUTHORIZATION'];48}4950if(empty($_SERVER['PHP_AUTH_DIGEST'])) {51header('WWW-Authenticate: Digest realm="'.$realm.52'",qop="auth",nonce="'.uniqid().'",opaque="'.md5($realm).'"');53header('HTTP/1.1 401 Unauthorized');54if($fail_msg!=NULL)55die($fail_msg);56if($fail_url!=NULL)57die("<script>window.location.href = '$fail_url'</script>");58exit;59}6061//analyze the PHP_AUTH_DIGEST variable62if(!($data= self::http_digest_parse($_SERVER['PHP_AUTH_DIGEST'])) || !isset($users[$data['username']])){63header('WWW-Authenticate: Digest realm="'.$realm.64'",qop="auth",nonce="'.uniqid().'",opaque="'.md5($realm).'"');65header('HTTP/1.1 401 Unauthorized');66if($fail_msg!=NULL)67die($fail_msg);68if($fail_url!=NULL)69die("<script>window.location.href = '$fail_url'</script>");70exit;71}7273//generate the valid response74$A1=md5($data['username'] . ':' .$realm. ':' .$users[$data['username']]);75$A2=md5($_SERVER['REQUEST_METHOD'].':'.$data['uri']);76$valid_response=md5($A1.':'.$data['nonce'].':'.$data['nc'].':'.$data['cnonce'].':'.$data['qop'].':'.$A2);7778if($data['response'] !=$valid_response){79header('HTTP/1.1 401 Unauthorized');80header('WWW-Authenticate: Digest realm="'.$realm.81'",qop="auth",nonce="'.uniqid().'",opaque="'.md5($realm).'"');82if($fail_msg!=NULL)83die($fail_msg);84if($fail_url!=NULL)85die("<script>window.location.href = '$fail_url'</script>");86exit;87}8889//ok, valid username & password90return$data['username'];91}9293/**94* Method to parse the http auth header, works with IE.95*96* Internet Explorer returns a qop="xxxxxxxxxxx" in the header instead of qop=xxxxxxxxxxx as most browsers do.97*98* @param string $txt header string to parse99* @return array An assoc array of the digest auth session100*/101privatestaticfunctionhttp_digest_parse($txt)102{103$res=preg_match("/username=\"([^\"]+)\"/i",$txt,$match);104$data['username'] = (isset($match[1]))?$match[1]:null;105$res=preg_match('/nonce=\"([^\"]+)\"/i',$txt,$match);106$data['nonce'] =$match[1];107$res=preg_match('/nc=([0-9]+)/i',$txt,$match);108$data['nc'] =$match[1];109$res=preg_match('/cnonce=\"([^\"]+)\"/i',$txt,$match);110$data['cnonce'] =$match[1];111$res=preg_match('/qop=([^,]+)/i',$txt,$match);112$data['qop'] =str_replace('"','',$match[1]);113$res=preg_match('/uri=\"([^\"]+)\"/i',$txt,$match);114$data['uri'] =$match[1];115$res=preg_match('/response=\"([^\"]+)\"/i',$txt,$match);116$data['response'] =$match[1];117return$data;118}119120121}
调用方法:
1require_once(dirname(__FILE__)."/DooDigestAuth.php");2DooDigestAuth::http_auth('example.com',array('admin'=>"123456789"));
phpweb授权登录可有效防止后台暴力破解
下载地址:http://files.cnblogs.com/files/func/DooDigestAuth.zip