Imbo\EventListener\Authenticate::authenticate PHP Method

authenticate() public method

public authenticate ( Imbo\EventManager\EventInterface $event )
$event Imbo\EventManager\EventInterface
    public function authenticate(EventInterface $event)
    {
        $response = $event->getResponse();
        $request = $event->getRequest();
        $config = $event->getConfig();
        // Whether or not the authentication info is in the request headers
        $fromHeaders = $request->headers->has('x-imbo-authenticate-timestamp') && $request->headers->has('x-imbo-authenticate-signature');
        // Fetch timestamp header, fallback to query param
        $timestamp = $request->headers->get('x-imbo-authenticate-timestamp', $request->query->get('timestamp'));
        if (!$timestamp) {
            $exception = new RuntimeException('Missing authentication timestamp', 400);
            $exception->setImboErrorCode(Exception::AUTH_MISSING_PARAM);
        } else {
            if (!$this->timestampIsValid($timestamp)) {
                $exception = new RuntimeException('Invalid timestamp: ' . $timestamp, 400);
                $exception->setImboErrorCode(Exception::AUTH_INVALID_TIMESTAMP);
            } else {
                if ($this->timestampHasExpired($timestamp)) {
                    $exception = new RuntimeException('Timestamp has expired: ' . $timestamp, 400);
                    $exception->setImboErrorCode(Exception::AUTH_TIMESTAMP_EXPIRED);
                }
            }
        }
        if (isset($exception)) {
            throw $exception;
        }
        // Fetch signature header, fallback to query param
        $signature = $request->headers->get('x-imbo-authenticate-signature', $request->query->get('signature'));
        if (!$signature) {
            $exception = new RuntimeException('Missing authentication signature', 400);
            $exception->setImboErrorCode(Exception::AUTH_MISSING_PARAM);
        }
        if (isset($exception)) {
            throw $exception;
        }
        $publicKey = $request->getPublicKey();
        $privateKey = $event->getAccessControl()->getPrivateKey($publicKey);
        $url = $request->getRawUri();
        if (!$fromHeaders) {
            // Remove the signature and timestamp from the query parameters as they are not used
            // when generating the HMAC
            $url = rtrim(preg_replace('/(?<=(\\?|&))(signature|timestamp)=[^&]+&?/', '', $url), '&?');
        }
        // See if we should modify the protocol for the incoming request
        $uris = [$url];
        $protocol = $config['authentication']['protocol'];
        if ($protocol === 'both') {
            $uris = [preg_replace('#^https?#', 'http', $url), preg_replace('#^https?#', 'https', $url)];
        } else {
            if (in_array($protocol, ['http', 'https'])) {
                $uris = [preg_replace('#^https?#', $protocol, $url)];
            }
        }
        // Add the URL used for auth to the response headers
        $response->headers->set('X-Imbo-AuthUrl', implode(', ', $uris));
        foreach ($uris as $uri) {
            if ($this->signatureIsValid($request->getMethod(), $uri, $publicKey, $privateKey, $timestamp, $signature)) {
                return;
            }
        }
        $exception = new RuntimeException('Signature mismatch', 400);
        $exception->setImboErrorCode(Exception::AUTH_SIGNATURE_MISMATCH);
        throw $exception;
    }

Usage Example

Ejemplo n.º 1
0
 /**
  * @dataProvider getRewrittenSignatureData
  * @covers Imbo\EventListener\Authenticate::authenticate
  * @covers Imbo\EventListener\Authenticate::signatureIsValid
  * @covers Imbo\EventListener\Authenticate::timestampIsValid
  * @covers Imbo\EventListener\Authenticate::timestampHasExpired
  */
 public function testApprovesSignaturesWhenConfigurationForcesProtocol($serverUrl, $protocol, $authHeader, $shouldMatch, $signature, $timestamp)
 {
     if (!$shouldMatch) {
         $this->setExpectedException('Imbo\\Exception\\RuntimeException', 'Signature mismatch', 400);
     }
     $this->accessControl->expects($this->once())->method('getPrivateKey')->will($this->returnValue('key'));
     $this->headers->expects($this->at(0))->method('has')->with('x-imbo-authenticate-timestamp')->will($this->returnValue(false));
     $this->headers->expects($this->at(1))->method('get')->with('x-imbo-authenticate-timestamp', $timestamp)->will($this->returnValue($timestamp));
     $this->headers->expects($this->at(2))->method('get')->with('x-imbo-authenticate-signature', $signature)->will($this->returnValue($signature));
     $this->query->expects($this->at(0))->method('get')->with('timestamp')->will($this->returnValue($timestamp));
     $this->query->expects($this->at(1))->method('get')->with('signature')->will($this->returnValue($signature));
     $this->request->expects($this->once())->method('getRawUri')->will($this->returnValue($serverUrl));
     $this->request->expects($this->once())->method('getPublicKey')->will($this->returnValue('christer'));
     $this->request->expects($this->any())->method('getMethod')->will($this->returnValue('PUT'));
     $responseHeaders = $this->getMock('Symfony\\Component\\HttpFoundation\\ResponseHeaderBag');
     $responseHeaders->expects($this->once())->method('set')->with('X-Imbo-AuthUrl', $authHeader);
     $this->response->headers = $responseHeaders;
     $this->listener->authenticate($this->getEventMock(['authentication' => ['protocol' => $protocol]]));
 }
All Usage Examples Of Imbo\EventListener\Authenticate::authenticate