Skip to content

Instantly share code, notes, and snippets.

@gadiener
Created June 3, 2016 15:25
Show Gist options
  • Save gadiener/d39adc014122ed95cb983d74faeb0004 to your computer and use it in GitHub Desktop.
Save gadiener/d39adc014122ed95cb983d74faeb0004 to your computer and use it in GitHub Desktop.
Digest HTTP Authentication class for core
<?php
/**
* Digest HTTP Authentication class
*
* PHP version 5.5
*
* @author Gabriele Diener <gabriele.diener@caffeina.com>
*/
class DigestAuth {
protected static $realm = "Restricted area",
$data = false,
$needed_parts = [
'nonce' => true,
'nc' => true,
'cnonce' => true,
'qop' => true,
'username' => true,
'uri' => true,
'response' => true
];
public static function authenticate( $callback = false ) {
/**
* analyze the PHP_AUTH_DIGEST variable
*/
if (
Request::server( 'PHP_AUTH_DIGEST', false ) ||
!( static::$data = static::parse( Request::server( 'PHP_AUTH_DIGEST', false ) ) ) ||
!Options::get( "auth.clients." . static::$data['username'], false ) ||
static::$data['response'] !== static::validResponse()
) {
return is_callable($callback) ? call_user_func($callback) : false;
}
return true;
}
public static function failHeader() {
return [ "WWW-Authenticate", 'Digest realm="' . static::$realm . '",qop="auth",nonce="' . uniqid() . '",opaque="' . Hash::make(static::$realm) . '"' ];
}
protected static function parse($txt) {
$needed = static::$needed_parts;
preg_match_all( '@(' . implode( '|', array_keys($needed) ) . ')=(?:([\'"])([^\2]+?)\2|([^\s,]+))@', $txt, $matches, PREG_SET_ORDER );
foreach ( $matches as $m ) {
$data[$m[1]] = $m[3] ? $m[3] : $m[4];
unset($needed[$m[1]]);
}
return $needed ? false : $data;
}
/**
* generate the valid response
*/
protected static function validResponse() {
if (!static::$data) return false;
$hash = [
Hash::make( static::$data['username'] . ":{$realm}:" . Options::get( "auth.clients." . static::$data['username'], false ) ),
Hash::make( Request::server('REQUEST_METHOD') . ":" . static::$data['uri'] )
];
return Hash::make("{$hash[0]}:" . static::$data['nonce'] . ":" . static::$data['nc'] . ":" . static::$data['cnonce'] . ":" . static::$data['qop'] . ":{$hash[2]}");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment