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 BadCredentialsException('Invalid signature.'); } public function createToken(Request $req, $provider_key) { // api key header $api_key = $req->headers->get(self::HEADER_API_KEY); if ($api_key == null) throw new BadCredentialsException('No API key sent.'); // check date from headers $hdate_string = $req->headers->get(self::HEADER_DATE); if ($hdate_string == null) throw new BadCredentialsException('No date specified.'); $hdate = DateTime::createFromFormat(self::DATE_FORMAT, $hdate_string); if ($hdate == null) throw new BadCredentialsException('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 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); return new PreAuthenticatedToken( 'anonymous', $api_key, $provider_key ); } public function supportsToken(TokenInterface $token, $provider_key) { return $token instanceof PreAuthenticatedToken && $token->getProviderKey() === $provider_key; } public function authenticateToken(TokenInterface $token, UserProviderInterface $user_provider, $provider_key) { if (!$user_provider instanceof APIKeyUserProvider) { throw new \InvalidArgumentException( sprintf( 'The user provider must be an instance of APIKeyUserProvider (%s was given).', get_class($user_provider) ) ); } $api_key = $token->getCredentials(); $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) ); } */ if (!$user) throw new CustomUserMessageAuthenticationException('Invalid API Key'); // $user = $user_provider->loadUserByUsername($username); return new PreAuthenticatedToken( $user, $api_key, $provider_key, $user->getRoles() ); } public function onAuthenticationFailure(Request $req, AuthenticationException $exception) { $data = [ 'success' => false, 'error' => [ 'message' => $exception->getMessage(), ], ]; return new JsonResponse($data, 401); } }