Last active
January 28, 2021 00:23
-
-
Save danielbachhuber/6c09dd2fcd1a9c4ef252 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Make a remote GET using DIGEST authentication. | |
* | |
* DIGEST authenticated requests require two GET requests: | |
* 1. GET the www-authenticate header for nonce, realm, opaque, and other values | |
* 2. GET the expected response body by constructing an 'Authorization' header | |
* with nonce, realm, and other values provided by the server. | |
* | |
* @license MIT | |
* | |
* @param string $url API URL supporting DIGEST authentication. | |
* @param string $username Username to be used in authentication. | |
* @param string $password Password to be used in authentication. | |
* @return string|false Response body on success, false on some form of failure. | |
*/ | |
function hb_digest_auth_remote_get( $url, $username, $password ) { | |
/* | |
* Makes an initial request for the server's provided headers | |
*/ | |
$response = wp_remote_get( $url, $request ); | |
$header = wp_remote_retrieve_header( $response, 'www-authenticate' ); | |
if ( empty( $header ) ) { | |
return false; | |
} | |
/* | |
* Parses the 'www-authenticate' header for nonce, realm and other values. | |
*/ | |
preg_match_all( '#(([\w]+)=["]?([^\s"]+))#', $header, $matches ); | |
$server_bits = array(); | |
foreach( $matches[2] as $i => $key ) { | |
$server_bits[ $key ] = $matches[3][ $i ]; | |
} | |
$nc = '00000001'; | |
$path = parse_url( $url, PHP_URL_PATH ); | |
$client_nonce = uniqid(); | |
$ha1 = md5( $username . ':' . $server_bits['realm'] . ':' . $password ); | |
$ha2 = md5( 'GET:' . $path ); | |
// The order of this array matters, because it affects resulting hashed val | |
$response_bits = array( | |
$ha1, | |
$server_bits['nonce'], | |
$nc, | |
$client_nonce, | |
$server_bits['qop'], | |
$ha2 | |
); | |
$digest_header_values = array( | |
'username' => '"' . $username . '"', | |
'realm' => '"' . $server_bits['realm'] . '"', | |
'nonce' => '"' . $server_bits['nonce'] . '"', | |
'uri' => '"' . $path . '"', | |
'response' => '"' . md5( implode( ':', $response_bits ) ) . '"', | |
'opaque' => '"' . $server_bits['opaque'] . '"', | |
'qop' => $server_bits['qop'], | |
'nc' => $nc, | |
'cnonce' => '"' . $client_nonce . '"', | |
); | |
$digest_header = 'Digest '; | |
foreach( $digest_header_values as $key => $value ) { | |
$digest_header .= $key . '=' . $value . ', '; | |
} | |
$digest_header = rtrim( $digest_header, ', ' ); | |
$request = array( | |
'headers' => array( | |
'Authorization' => $digest_header, | |
), | |
); | |
$response = wp_remote_get( $url, $request ); | |
if ( 200 !== wp_remote_retrieve_response_code( $response ) ) { | |
return false; | |
} | |
return wp_remote_retrieve_body( $response ); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Note that on line 23 (
$response = wp_remote_get( $url, $request );
)$request
is not defined.