4

I'm using the pecl oAuth library, is it possible to build a body signed oauth request that looks like:

POST http://www.imsglobal.org/developers/BLTI/service_handle.php HTTP/1.0
Host: 127.0.0.1:80
Content-Length: 757
Authorization: OAuth realm="",oauth_version="1.0",
oauth_nonce="29f90c047a44b2ece73d00a09364d49b",
oauth_timestamp="1313350943",oauth_consumer_key="lmsng.school.edu",
oauth_body_hash="v%2BxFnmDSHV%2Fj29qhxLwkFILrtPo%3D",
oauth_signature_method="HMAC-SHA1",
oauth_signature="8auRpRdPY2KRXUrOyz3HKCs92y8%3D"
Content-type: application/xml
<?xml version = "1.0" encoding = "UTF-8"?>
... more xml data ...

I'm trying to communicate with Instructure's Canvas LMS using the IMS Global LTI standard interface. The Outcomes Service lets you send scores back to the LMS using oauth signed xml messages

Maen
  • 10,603
  • 3
  • 45
  • 71
iturgeon
  • 297
  • 3
  • 12

2 Answers2

5

As it turns out pecl oAuth doesn't support oaut_body_hash currently.

I ended up using the oAuth library from this google code repository http://code.google.com/p/oauth/ and computing the body has myself:

$bodyHash = base64_encode(sha1($body, TRUE)); // build oauth_body_hash
$consumer = new \OAuthConsumer($key, $secret);
$request = \OAuthRequest::from_consumer_and_token($consumer, '', 'POST', $endpoint, array('oauth_body_hash' => $bodyHash) );
$request->sign_request(new \OAuthSignatureMethod_HMAC_SHA1(), $consumer, '');
$header = $request->to_header() . "\r\nContent-Type: application/xml\r\n"; // add content type header
iturgeon
  • 297
  • 3
  • 12
1

The standard OAuth::generateSignature function permits extra parameters as a third argument. This can be used to pass a custom body hash parameter:

$oauth = new OAuth($credentials["oauthKey"], $credentials["oauthSecret"]);

$timestamp = time();
$oauth->setTimestamp($timestamp);

$nonce = mt_rand();
$oauth->setNonce($nonce);

$bodyHash = base64_encode(sha1($content, true)); // $content contains the body
$sig = $oauth->generateSignature('GET', $url, Array("oauth_body_hash" => $bodyHash));

We can then use this to build our OAuth header:

$header = array
(
    'Content-Type: application/xml'
);
$header[] = 'Authorization: OAuth '.
            'oauth_version="1.0",'.
            'oauth_nonce="'.$nonce.'",'.
            'oauth_timestamp="'.$timestamp.'",'.
            'oauth_body_hash="'.$bodyHash.'",'.
            'oauth_consumer_key="'.$credentials["oauthKey"].'",'.
            'oauth_signature_method="HMAC-SHA1",'.
            'oauth_signature="'.urlencode($sig).'"';
janw
  • 8,758
  • 11
  • 40
  • 62