Skip to content

Instantly share code, notes, and snippets.

@kirkegaard
Last active December 17, 2015 07:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kirkegaard/5575976 to your computer and use it in GitHub Desktop.
Save kirkegaard/5575976 to your computer and use it in GitHub Desktop.
<?php
class Auth
{
protected $realm = 'My Realm';
protected $user = array();
protected $isAuthenticated = false;
protected $nonce = null;
protected $digest = null;
function __construct($options)
{
$this->nonce = uniqid();
$this->user = $options['user'];
$this->realm = $options['realm'];
$this->digest = $this->getDigest();
if($this->digest != null && $this->validate()) {
$this->isAuthenticated = true;
}
}
public function login()
{
header('WWW-Authenticate: Digest realm="' . $this->realm . '",qop="auth",nonce="' . $this->nonce . '",opaque="' . md5($this->realm) . '"');
header('HTTP/1.0 401 Unauthorized');
}
public function logout()
{
header('HTTP/1.1 401 Unauthorized');
unset($_SERVER['PHP_AUTH_DIGEST']);
$this->isAuthenticated = false;
return true;
}
protected function validate()
{
$digestParse = $this->digestParse($this->digest);
$a1 = md5("{$this->user['username']}:{$this->realm}:{$this->user['password']}");
$a2 = md5("{$_SERVER['REQUEST_METHOD']}:{$digestParse['uri']}");
$response = md5("{$a1}:{$digestParse['nonce']}:{$digestParse['nc']}:{$digestParse['cnonce']}:{$digestParse['qop']}:{$a2}");
if($digestParse['response'] != $response) {
return false;
}
return true;
}
protected function getDigest()
{
if (isset($_SERVER['PHP_AUTH_DIGEST'])) {
$digest = $_SERVER['PHP_AUTH_DIGEST'];
} elseif (isset($_SERVER['HTTP_AUTHENTICATION'])) {
if (strpos(strtolower($_SERVER['HTTP_AUTHENTICATION']),'digest')===0) {
$digest = substr($_SERVER['HTTP_AUTHORIZATION'], 7);
}
} else {
return false;
}
return $digest;
}
protected function digestParse($digest)
{
// protect against missing data
$needed_parts = array('nonce'=>1, 'nc'=>1, 'cnonce'=>1, 'qop'=>1, 'username'=>1, 'uri'=>1, 'response'=>1);
$data = array();
preg_match_all('@(\w+)=(?:(?:")([^"]+)"|([^\s,$]+))@', $digest, $matches, PREG_SET_ORDER);
foreach ($matches as $m) {
$data[$m[1]] = $m[2] ? $m[2] : $m[3];
unset($needed_parts[$m[1]]);
}
return $needed_parts ? false : $data;
}
public function isAuthenticated()
{
return $this->isAuthenticated;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment