/**
  * @param TokenInterface $token
  *
  * @return TokenInterface
  */
 public function authenticate(TokenInterface $token)
 {
     $now = new \DateTime();
     /** @var ApiUnauthenticatedUserToken $token */
     $clientTokenInfos = $this->validateClientToken($token->getClientTokenInfos(), $now);
     $userTokenInfos = $this->validateUserToken($token->getUserTokenInfos(), $now);
     $username = $token->getUsername();
     if ($token->isImpersonating()) {
         /** @var ApiUser $sudoer */
         $sudoer = $this->userProvider->loadUserByUsername($token->getUsername());
         if (!$sudoer->isAllowedToSwitch()) {
             throw new MissingSudoPrivilegeException();
         }
         $username = $token->getImpersonatedUserInfos()['id'];
     }
     return new ApiAuthenticatedUserToken($clientTokenInfos, $userTokenInfos, $this->userProvider->loadUserByUsername($username));
 }