/**
  * {@inheritdoc}
  */
 public function authenticate(SecurityContextInterface $context, TokenInterface $token, HttpRequest $request)
 {
     if (!$token instanceof FormAuthToken) {
         throw new SecurityException(sprintf('Token %s not supported by provider %s', get_class($token), get_class($this)));
     }
     $this->failedLogin = false;
     $this->username = $token->getUsername();
     $this->guard = bin2hex(random_bytes($this->guardByteCount));
     $path = trim($request->getUri()->getPath(false), '/');
     $loginPath = trim((new Uri($this->getLoginUri()))->getPath(false), '/');
     $logoutPath = trim((new Uri($this->getLogoutUri()))->getPath(false), '/');
     $isLogin = $path === $loginPath;
     $isLogout = $path === $logoutPath;
     $session = $context->getSession();
     if ($isLogout) {
         $session->remove($this->getKey());
         $token->setPrincipal(new AnonymousPrincipal());
         $token->setStatus(TokenInterface::AUTHENTICATION_SUCCESSFUL);
         return;
     }
     if ($isLogin) {
         try {
             if ($request->isPost(false)) {
                 $identity = $token->getUsername();
                 $password = $token->getPassword();
                 // Fetch user independent of guard in order to prevent leakage of timing information.
                 $principal = $this->getPrincipalProvider()->findPrincipalUsingPassword($identity, $password);
                 // Invalidate when guard fails.
                 if (!$token->isGuarded()) {
                     $principal = NULL;
                 }
                 if ($principal !== NULL) {
                     $session = $context->getSession();
                     $data = (array) $session->get($this->getKey(), NULL);
                     $data[self::SESSION_IDENTITY] = (string) $principal->getIdentity();
                     $session->set($this->getKey(), $data);
                     if (array_key_exists(self::SESSION_URI, $data)) {
                         $uri = $data[self::SESSION_URI];
                         unset($data[self::SESSION_URI]);
                         $session->set($this->getKey(), $data);
                         $response = new HttpResponse(Http::REDIRECT_TEMPORARY);
                         $response->setHeader('Location', $uri);
                         return $response;
                     }
                     $token->setPrincipal($principal);
                     $token->setStatus(TokenInterface::AUTHENTICATION_SUCCESSFUL);
                     return;
                 }
                 $this->failedLogin = true;
             }
             $token->setPrincipal(new AnonymousPrincipal());
             $token->setStatus(TokenInterface::AUTHENTICATION_SUCCESSFUL);
             return;
         } finally {
             $data = (array) $session->get($this->getKey(), []);
             $data[self::SESSION_GUARD] = $this->guard;
             $session->set($this->getKey(), $data);
         }
     }
 }
 public function createChallenge(SecurityContextInterface $context)
 {
     // FIXME: Need to create (and store!) a dynamic challenge... could use Session for storage.
     return '12345678';
     return $context->getRandomGenerator()->generateRaw(8);
 }