From 3ac8b8e53d5ad6c5e29a5f6d2e82ac2e5ff85fe4 Mon Sep 17 00:00:00 2001 From: Kendrick Chan Date: Tue, 23 Oct 2018 03:01:52 +0800 Subject: [PATCH] Fix signature issue and remove old token subscriber #164 --- .../api-bundle/Command/UserCreateCommand.php | 4 +- .../EventSubscriber/TokenSubscriber.php | 122 ------------------ .../Security/APIKeyAuthenticator.php | 51 ++++---- config/services.yaml | 5 - 4 files changed, 26 insertions(+), 156 deletions(-) delete mode 100644 catalyst/api-bundle/EventSubscriber/TokenSubscriber.php diff --git a/catalyst/api-bundle/Command/UserCreateCommand.php b/catalyst/api-bundle/Command/UserCreateCommand.php index 13715e65..cea9682c 100644 --- a/catalyst/api-bundle/Command/UserCreateCommand.php +++ b/catalyst/api-bundle/Command/UserCreateCommand.php @@ -41,8 +41,8 @@ class UserCreateCommand extends Command $this->em->persist($user); $this->em->flush(); - $output->write('API Key - ' . $user->getAPIKey()); - $output->write('Secret Key - ' . $user->getSecretKey()); + $output->write('API Key - ' . $user->getAPIKey() . "\n"); + $output->write('Secret Key - ' . $user->getSecretKey() . "\n"); } diff --git a/catalyst/api-bundle/EventSubscriber/TokenSubscriber.php b/catalyst/api-bundle/EventSubscriber/TokenSubscriber.php deleted file mode 100644 index 8a44f99e..00000000 --- a/catalyst/api-bundle/EventSubscriber/TokenSubscriber.php +++ /dev/null @@ -1,122 +0,0 @@ - em = $em; - } - - protected function getSecretKey($api_key) - { - return 'sldkfjlksdjflksdjflksdjflsjf'; - } - - protected function validateSignature($req, $hdate_string, $secret_key, $sig) - { - // get needed params for generation - $method = $req->getRealMethod(); - $uri = $req->getRequestUri(); - - $elements = [$method, $uri, $hdate_string, $secret_key]; - $sig_source = implode('|', $elements); - - error_log($sig_source); - - // generate signature - $raw_sig = hash_hmac('sha1', $sig_source, $secret_key, true); - $enc_sig = base64_encode($raw_sig); - - error_log($enc_sig); - - if ($enc_sig != trim($sig)) - throw new AccessDeniedHttpException('Invalid signature.'); - - } - - public function onKernelController(FilterControllerEvent $event) - { - $controller = $event->getController(); - - // not a controller class? (docs said to handle) - if (!is_array($controller)) - return; - - - // not an api controller - if (!($controller[0] instanceof APIController)) - return; - - $req = $event->getRequest(); - - // check date from headers - $headers = $req->headers->all(); - $hdate_string = $req->headers->get(self::HEADER_DATE); - if ($hdate_string == null) - throw new AccessDeniedHttpException('No date specified.'); - - $hdate = DateTime::createFromFormat(self::DATE_FORMAT, $hdate_string); - if ($hdate == null) - throw new AccessDeniedHttpException('Invalid date specified.'); - - // get number of seconds difference - $date_now = new DateTime(); - $date_diff = abs($date_now->getTimestamp() - $hdate->getTimestamp()); - - // time difference is too much - if ($date_diff > self::TIME_LIMIT) - throw new AccessDeniedHttpException('Clock synchronization error.'); - - // api key header - $api_key = $req->headers->get(self::HEADER_API_KEY); - if ($api_key == null) - throw new AccessDeniedHttpException('No api key sent.'); - - // check valid api key - $secret_key = $this->getSecretKey($api_key); - - // signature header - $sig = $req->headers->get(self::HEADER_SIGNATURE); - if ($sig == null) - throw new AccessDeniedHttpException('No signature sent.'); - - // check valid signature - $this->validateSignature($req, $hdate_string, $secret_key, $sig); - - return; - } - - public static function getSubscribedEvents() - { - return [ - KernelEvents::CONTROLLER => 'onKernelController', - ]; - } -} diff --git a/catalyst/api-bundle/Security/APIKeyAuthenticator.php b/catalyst/api-bundle/Security/APIKeyAuthenticator.php index c73093e7..a21c2ac6 100644 --- a/catalyst/api-bundle/Security/APIKeyAuthenticator.php +++ b/catalyst/api-bundle/Security/APIKeyAuthenticator.php @@ -40,13 +40,14 @@ class APIKeyAuthenticator implements SimplePreAuthenticatorInterface, Authentica return 'sldkfjlksdjflksdjflksdjflsjf'; } - protected function validateSignature($req, $hdate_string, $secret_key, $sig) + protected function validateSignature($creds, $secret_key) { - // get needed params for generation - $method = $req->getRealMethod(); - $uri = $req->getRequestUri(); - - $elements = [$method, $uri, $hdate_string, $secret_key]; + $elements = [ + $creds['method'], + $creds['uri'], + $creds['date'], + $secret_key, + ]; $sig_source = implode('|', $elements); error_log($sig_source); @@ -57,8 +58,8 @@ class APIKeyAuthenticator implements SimplePreAuthenticatorInterface, Authentica error_log($enc_sig); - if ($enc_sig != trim($sig)) - throw new BadCredentialsException('Invalid signature.'); + if ($enc_sig != trim($creds['signature'])) + throw new CustomUserMessageAuthenticationException('Invalid signature.'); } @@ -86,20 +87,23 @@ class APIKeyAuthenticator implements SimplePreAuthenticatorInterface, Authentica if ($date_diff > self::TIME_LIMIT) throw new BadCredentialsException('Clock synchronization error.'); - // check valid api key - $secret_key = $this->getSecretKey($api_key); - // signature header $sig = $req->headers->get(self::HEADER_SIGNATURE); if ($sig == null) throw new BadCredentialsException('No signature sent.'); - // check valid signature - $this->validateSignature($req, $hdate_string, $secret_key, $sig); + // credentials + $creds = [ + 'api_key' => $api_key, + 'date' => $hdate_string, + 'signature' => $sig, + 'method' => $req->getRealMethod(), + 'uri' => $req->getRequestUri(), + ]; return new PreAuthenticatedToken( 'anonymous', - $api_key, + $creds, $provider_key ); } @@ -121,24 +125,17 @@ class APIKeyAuthenticator implements SimplePreAuthenticatorInterface, Authentica ); } - $api_key = $token->getCredentials(); + $creds = $token->getCredentials(); + $api_key = $creds['api_key']; $user = $user_provider->getUserByAPIKey($api_key); - /* - $username = $user_provider->getUsernameForAPIKey($api_key); - - if (!$username) - { - // CAUTION: this message will be returned to the client - // (so don't put any un-trusted messages / error strings here) - throw new CustomUserMessageAuthenticationException( - sprintf('API Key "%s" does not exist.', $api_key) - ); - } - */ + // check if api key is valid if (!$user) throw new CustomUserMessageAuthenticationException('Invalid API Key'); + // check if signature is valid + $this->validateSignature($creds, $user->getSecretKey()); + // $user = $user_provider->loadUserByUsername($username); return new PreAuthenticatedToken( diff --git a/config/services.yaml b/config/services.yaml index b83a0a5e..309d2129 100644 --- a/config/services.yaml +++ b/config/services.yaml @@ -76,11 +76,6 @@ services: $ip_address: "%env(APNS_REDIS_IP_ADDRESS)%" $port: "%env(APNS_REDIS_PORT)%" - Catalyst\APIBundle\EventSubscriber\TokenSubscriber: - arguments: - $em: "@doctrine.orm.entity_manager" - tags: ['kernel.event_subscriber'] - Catalyst\APIBundle\Security\APIKeyUserProvider: arguments: $em: "@doctrine.orm.entity_manager"