em = $em; } protected function getSecretKey($api_key) { return 'sldkfjlksdjflksdjflksdjflsjf'; } protected function validateSignature($creds, $secret_key) { $elements = [ $creds['method'], $creds['uri'], $creds['date'], $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($creds['signature'])) throw new CustomUserMessageAuthenticationException('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.'); // signature header $sig = $req->headers->get(self::HEADER_SIGNATURE); if ($sig == null) throw new BadCredentialsException('No signature sent.'); // credentials $creds = [ 'api_key' => $api_key, 'date' => $hdate_string, 'signature' => $sig, 'method' => $req->getRealMethod(), 'uri' => $req->getRequestUri(), ]; return new PreAuthenticatedToken( 'anonymous', $creds, $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) ) ); } $creds = $token->getCredentials(); $api_key = $creds['api_key']; $user = $user_provider->getUserByAPIKey($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( $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); } }