/**
  * {@inheritDoc}
  */
 public function authenticate(RequestInterface $request)
 {
     $authHeader = AuthorizationHeader::createFromRequest($request);
     $signature = $authHeader->getSignature();
     // Check whether the timestamp is valid.
     $comparison = $this->compareTimestamp($request, $this->expiry);
     if (-1 == $comparison) {
         throw new TimestampOutOfRangeException('Request is too old');
     } elseif (1 == $comparison) {
         throw new TimestampOutOfRangeException('Request is too far in the future');
     }
     // Load the API Key and sign the request.
     if (!($key = $this->keyLoader->load($authHeader->getId()))) {
         throw new KeyNotFoundException('API key not found');
     }
     // Generate the signature from the passed authorization header.
     // If it matches the request signature, the request is authenticated.
     $compareRequest = $request->withoutHeader('Authorization');
     $authHeaderBuilder = new AuthorizationHeaderBuilder($compareRequest, $key);
     $authHeaderBuilder->setRealm($authHeader->getRealm());
     $authHeaderBuilder->setId($authHeader->getId());
     $authHeaderBuilder->setNonce($authHeader->getNonce());
     $authHeaderBuilder->setVersion($authHeader->getVersion());
     $authHeaderBuilder->setCustomHeaders($authHeader->getCustomHeaders());
     $compareAuthHeader = $authHeaderBuilder->getAuthorizationHeader();
     $compareSignature = $compareAuthHeader->getSignature();
     if (!hash_equals($compareSignature, $signature)) {
         throw new InvalidSignatureException('Signature not valid');
     }
     return $key;
 }
 /**
  * Ensures a response can be authenticated.
  */
 public function testIsAuthentic()
 {
     $realm = 'Pipet service';
     $nonce = 'd1954337-5319-4821-8427-115542e08d10';
     $timestamp = 1432075982;
     $signature = 'LusIUHmqt9NOALrQ4N4MtXZEFE03MjcDjziK+vVqhvQ=';
     $requestHeaders = ['X-Authorization-Timestamp' => $timestamp];
     $request = new Request('GET', 'http://example.com', $requestHeaders);
     $authHeaderBuilder = new AuthorizationHeaderBuilder($request, $this->authKey);
     $authHeaderBuilder->setRealm($realm);
     $authHeaderBuilder->setId($this->authKey->getId());
     $authHeaderBuilder->setNonce($nonce);
     $authHeader = $authHeaderBuilder->getAuthorizationHeader();
     $requestSigner = new MockRequestSigner($this->authKey, $realm, new Digest(), $authHeader);
     $signedRequest = $requestSigner->signRequest($request);
     $responseHeaders = ['X-Server-Authorization-HMAC-SHA256' => $signature];
     $response = new Response(200, $responseHeaders);
     $authenticator = new ResponseAuthenticator($signedRequest, $this->authKey);
     $this->assertTrue($authenticator->isAuthentic($response));
 }
 /**
  * Ensures the correct headers are generated when signing a request.
  */
 public function testSignRequest()
 {
     $headers = ['Content-Type' => 'text/plain', 'X-Authorization-Timestamp' => $this->timestamp];
     $request = new Request('GET', 'https://example.acquiapipet.net/v1.0/task-status/133?limit=10', $headers);
     $digest = new Digest();
     $authHeaderBuilder = new AuthorizationHeaderBuilder($request, $this->authKey, $digest);
     $authHeaderBuilder->setRealm($this->realm);
     $authHeaderBuilder->setId($this->authKey->getId());
     $authHeaderBuilder->setNonce('d1954337-5319-4821-8427-115542e08d10');
     $authHeader = $authHeaderBuilder->getAuthorizationHeader();
     $signer = new MockRequestSigner($this->authKey, $this->realm, $digest, $authHeader);
     $signedRequest = $signer->signRequest($request);
     $this->assertFalse($signedRequest->hasHeader('X-Authorization-Content-SHA256'));
     $this->assertTrue($signedRequest->hasHeader('X-Authorization-Timestamp'));
     $this->assertEquals($this->timestamp, $signedRequest->getHeaderLine('X-Authorization-Timestamp'));
     $this->assertTrue($signedRequest->hasHeader('Authorization'));
     $this->assertContains('signature="MRlPr/Z1WQY2sMthcaEqETRMw4gPYXlPcTpaLWS2gcc="', $signedRequest->getHeaderLine('Authorization'));
     // Ensure that we can get the AuthorizationHeader back from the request.
     $signedAuthRequest = $signer->getAuthorizedRequest($signedRequest);
     $this->assertContains('signature="MRlPr/Z1WQY2sMthcaEqETRMw4gPYXlPcTpaLWS2gcc="', $signedAuthRequest->getHeaderLine('Authorization'));
 }
 /**
  * Ensures the correct headers are added when the response is signed.
  */
 public function testSignResponse()
 {
     $authId = 'efdde334-fe7b-11e4-a322-1697f925ec7b';
     $authSecret = 'W5PeGMxSItNerkNFqQMfYiJvH14WzVJMy54CPoTAYoI=';
     $realm = 'Pipet service';
     $nonce = 'd1954337-5319-4821-8427-115542e08d10';
     $timestamp = 1432075982;
     $signature = 'LusIUHmqt9NOALrQ4N4MtXZEFE03MjcDjziK+vVqhvQ=';
     $authKey = new Key($authId, $authSecret);
     $headers = ['X-Authorization-Timestamp' => $timestamp];
     $request = new Request('GET', 'http://example.com', $headers);
     $authHeaderBuilder = new AuthorizationHeaderBuilder($request, $authKey);
     $authHeaderBuilder->setRealm($realm);
     $authHeaderBuilder->setId($authKey->getId());
     $authHeaderBuilder->setNonce($nonce);
     $authHeader = $authHeaderBuilder->getAuthorizationHeader();
     $requestSigner = new MockRequestSigner($authKey, $realm, new Digest(), $authHeader);
     $signedRequest = $requestSigner->signRequest($request);
     $response = new Response();
     $responseSigner = new ResponseSigner($authKey, $signedRequest);
     $signedResponse = $responseSigner->signResponse($response);
     $this->assertTrue($signedResponse->hasHeader('X-Server-Authorization-HMAC-SHA256'));
     $this->assertEquals($signature, $signedResponse->getHeaderLine('X-Server-Authorization-HMAC-SHA256'));
 }
Example #5
0
 /**
  * @dataProvider specFixtureProvider
  */
 public function testSpec($input, $expectations)
 {
     $key = new Key($input['id'], $input['secret']);
     $digest = new Digest();
     $headers = ['X-Authorization-Timestamp' => $input['timestamp'], 'Content-Type' => $input['content_type']];
     foreach ($input['headers'] as $header => $value) {
         $headers[$header] = $value;
     }
     $body = !empty($input['content_body']) ? $input['content_body'] : null;
     $request = new Request($input['method'], $input['url'], $headers, $body);
     $authHeaderBuilder = new AuthorizationHeaderBuilder($request, $key);
     $authHeaderBuilder->setRealm($input['realm']);
     $authHeaderBuilder->setId($input['id']);
     $authHeaderBuilder->setNonce($input['nonce']);
     $authHeaderBuilder->setVersion('2.0');
     $authHeaderBuilder->setCustomHeaders($input['signed_headers']);
     $authHeader = $authHeaderBuilder->getAuthorizationHeader();
     $requestSigner = new MockRequestSigner($key, $input['realm'], $digest, $authHeader);
     $signedRequest = $requestSigner->signRequest($request, $input['signed_headers']);
     $signedAuthHeader = $signedRequest->getHeaderLine('Authorization');
     $this->assertContains('id="' . $input['id'] . '"', $signedAuthHeader);
     $this->assertContains('nonce="' . $input['nonce'] . '"', $signedAuthHeader);
     $this->assertContains('realm="' . rawurlencode($input['realm']) . '"', $signedAuthHeader);
     $this->assertContains('signature="' . $expectations['message_signature'] . '"', $signedAuthHeader);
     $this->assertContains('version="2.0"', $signedAuthHeader);
     // Prove that the digest generates the correct signature.
     $signedMessage = $digest->sign($expectations['signable_message'], $input['secret']);
     $this->assertEquals($expectations['message_signature'], $signedMessage);
     // Prove that the authenticator can authenticate the request.
     $keyLoader = new MockKeyLoader([$input['id'] => $input['secret']] + $this->keys);
     $authenticator = new MockRequestAuthenticator($keyLoader, null, $input['timestamp']);
     $compareKey = $authenticator->authenticate($signedRequest);
     $this->assertEquals($compareKey->getId(), $input['id']);
     // Prove that the response signer generates the correct signature.
     $response = new Response(200, [], $expectations['response_body']);
     $responseSigner = new ResponseSigner($key, $signedRequest);
     $response = $responseSigner->signResponse($response);
     $this->assertTrue($response->hasHeader('X-Server-Authorization-HMAC-SHA256'));
     $this->assertEquals($expectations['response_signature'], $response->getHeaderLine('X-Server-Authorization-HMAC-SHA256'));
 }
Example #6
0
 /**
  * Builds an AuthorizationHeader object.
  *
  * @param \Psr\Http\Message\RequestInterface $request
  *   The request being signed.
  * @param string[] $customHeaders
  *   A list of custom header names. The values of the headers will be
  *   extracted from the request.
  *
  * @return \Acquia\Hmac\AuthorizationHeader
  *   The compiled authorizatio header object.
  */
 protected function buildAuthorizationHeader(RequestInterface $request, array $customHeaders = [])
 {
     $authHeaderBuilder = new AuthorizationHeaderBuilder($request, $this->key, $this->digest);
     $authHeaderBuilder->setRealm($this->realm);
     $authHeaderBuilder->setId($this->key->getId());
     $authHeaderBuilder->setCustomHeaders($customHeaders);
     return $authHeaderBuilder->getAuthorizationHeader();
 }
 public function testAuthorizationHeaderBuilder()
 {
     $key = new Key('e7fe97fa-a0c8-4a42-ab8e-2c26d52df059', 'bXlzZWNyZXRzZWNyZXR0aGluZ3Rva2VlcA==');
     $headers = ['X-Authorization-Timestamp' => '1432075982', 'Content-Type' => 'application/json'];
     $request = new Request('POST', 'http://example.com?test=true', $headers, 'body text');
     $builder = new AuthorizationHeaderBuilder($request, $key);
     $builder->setId($key->getId());
     $builder->setNonce('a9938d07-d9f0-480c-b007-f1e956bcd027');
     $builder->setVersion('2.0');
     $header = $builder->getAuthorizationHeader();
     $this->assertEquals($header->getId(), $key->getId());
     $this->assertEquals($header->getSignature(), 'f9G/Xu339hw1z2zHTOrHKNv1kWqvYHYI9Nu/phO5dPY=');
     $builder->setSignature('test');
     $header = $builder->getAuthorizationHeader();
     $this->assertEquals($header->getSignature(), 'test');
 }
 /**
  * Ensures the HTTP HMAC middleware registers correctly.
  */
 public function testRegisterPlugin()
 {
     $realm = 'Pipet service';
     $requestHeaders = ['X-Authorization-Timestamp' => '1432075982'];
     $request = new Request('GET', 'https://example.acquiapipet.net/v1.0/task-status/133?limit=10', $requestHeaders);
     $authHeaderBuilder = new AuthorizationHeaderBuilder($request, $this->authKey);
     $authHeaderBuilder->setRealm($realm);
     $authHeaderBuilder->setId('efdde334-fe7b-11e4-a322-1697f925ec7b');
     $authHeaderBuilder->setNonce('d1954337-5319-4821-8427-115542e08d10');
     $authHeader = $authHeaderBuilder->getAuthorizationHeader();
     $middleware = new MockHmacAuthMiddleware($this->authKey, $realm, [], $authHeader);
     $container = [];
     $history = Middleware::history($container);
     $responseHeaders = ['X-Server-Authorization-HMAC-SHA256' => 'LusIUHmqt9NOALrQ4N4MtXZEFE03MjcDjziK+vVqhvQ='];
     $response = new Response(200, $responseHeaders);
     $stack = new HandlerStack();
     $stack->setHandler(new MockHandler([$response]));
     $stack->push($middleware);
     $stack->push($history);
     $client = new Client(['base_uri' => 'https://example.acquiapipet.net/', 'handler' => $stack]);
     $client->send($request);
     $transaction = reset($container);
     $request = $transaction['request'];
     $expected = 'acquia-http-hmac realm="Pipet%20service",' . 'id="efdde334-fe7b-11e4-a322-1697f925ec7b",' . 'nonce="d1954337-5319-4821-8427-115542e08d10",' . 'version="2.0",' . 'headers="",' . 'signature="MRlPr/Z1WQY2sMthcaEqETRMw4gPYXlPcTpaLWS2gcc="';
     $this->assertEquals($expected, $request->getHeaderLine('Authorization'));
 }