title: Symfony Security with Guard : User logged in and immediately logged out
body: <p>I want to authenticate users from a webservice. I created a firewall and I use <strong>Guard</strong> and a custom user provider. </p>
  
  <p>Here is my problem : when I log in, the user is <strong>authenticated and immediately logged out after the first redirection</strong> (<code>web_profiler.intercept_redirects</code> at <code>true</code>helps me to deduce it).</p>
  
  <p>I don't know what in my code or my config can be responsible of this. I created an authenticator that extends <code>AbstractGuardAuthenticator</code>. In the method <code>checkCredentials()</code>, I call the webservice and the answer is successful.</p>
  
  <p>In <code>onAuthenticationSuccess()</code> method, I set a token given by the webservice in session and I redirect to the route the user was before the authentication is triggered. When the redirection is done, the user is no longer logged in.</p>
  
  <p>I explored another point: my firewall is configured to work with specific hosts thanks to <code>host</code> key under my firewall configuration:</p>
  
  <pre><code>customer_account:
      pattern: ^(?!/admin[/]*).*$ # all but /admin
      host: "%extranet_domain_one%|%extranet_domain_two%"
      anonymous: ~
      provider: customer_account
      form_login:
          login_path: customer_account_login
          check_path: customer_account_login
      guard:
         authenticators:
             - app.customer_web_service_authenticator
      logout:
         path: customer_account_logout
         target: /
  </code></pre>
  
  <p>Here are my <code>access_control</code>config:</p>
  
  <pre><code>access_control:
          - { host: "%extranet_domain_one%|%extranet_domain_two%", path: ^/connexion, roles: IS_AUTHENTICATED_ANONYMOUSLY }
          - { host: "%extranet_domain_one%|%extranet_domain_two%", path: ^/mot-de-passe, roles: IS_AUTHENTICATED_ANONYMOUSLY }
          - { host: "%extranet_domain_one%|%extranet_domain_two%", path: ^/, roles: ROLE_CUSTOMER_ACCOUNT }
  </code></pre>
  
  <p>In my provider, the method <code>loadUserByUsername()</code> returns a new user with the login and the token stored in session if it exists. </p>
  
  <p>Any idea?</p>
  
  <p><strong>Additional informations:</strong></p>
  
  <p><code>CustomerWebServiceAuthenticator</code>:</p>
  
  <pre><code>&lt;?php
  
  namespace AppBundle\Security;
  
  use AppBundle\Security\User\CustomerAccount;
  use AppBundle\Security\User\CustomerAccountUserProvider;
  use AppBundle\Services\Webservice;
  use AppBundle\Services\MultisiteHelper;
  use Symfony\Component\HttpFoundation\RedirectResponse;
  use Symfony\Component\HttpFoundation\Request;
  use Symfony\Component\HttpFoundation\Session\SessionInterface;
  use Symfony\Component\Routing\RouterInterface;
  use Symfony\Component\Security\Core\Exception\CustomUserMessageAuthenticationException;
  use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
  use Symfony\Component\Security\Core\Security;
  use Symfony\Component\Security\Core\User\UserInterface;
  use Symfony\Component\Security\Guard\AbstractGuardAuthenticator;
  use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
  use Symfony\Component\Security\Core\Exception\AuthenticationException;
  use Symfony\Component\Security\Core\User\UserProviderInterface;
  
  /**
   * Class CustomerWebServiceAuthenticator
   *
   * @package AppBundle\Security
   */
  class CustomerWebServiceAuthenticator extends AbstractGuardAuthenticator
  {
  
      /** @var webservice */
      protected $webservice;
  
      /** @var MultisiteHelper */
      protected $multisiteHelper;
  
      /** @var \Symfony\Component\Routing\RouterInterface */
      protected $router;
  
      /** @var SessionInterface */
      protected $session;
  
      /**
       * Indique si le site s'exécute en mode développement.
       *
       * @var boolean
       */
      private $dev;
  
      /**
       * Default message for authentication failure.
       *
       * @var string
       */
      private $failMessage = 'Mot de passe ou e-mail invalide';
  
      /**
       * WebServiceAuthenticator constructor.
       *
       * @param Webservice $webservice
       * @param MultisiteHelper  $multisiteHelper
       * @param RouterInterface  $router
       * @param SessionInterface $session
       * @param string $kernelEnvironment
       */
      public function __construct(
          Webservice $webservice,
          MultisiteHelper $multisiteHelper,
          RouterInterface $router,
          SessionInterface $session,
          $kernelEnvironment
      ) {
          $this-&gt;webservice = $webservice;
          $this-&gt;multisiteHelper  = $multisiteHelper;
          $this-&gt;router           = $router;
          $this-&gt;session          = $session;
          $this-&gt;dev              = $kernelEnvironment === 'dev';
      }
  
      /**
       * {@inheritdoc}
       * @param Request $request
       *
       * @return array|null
       */
      public function getCredentials(Request $request)
      {
          $url = $request-&gt;getRequestUri();
  
          if ($url !== $this-&gt;router-&gt;generate('customer_account_login') || !$request-&gt;isMethod('POST')) {
              return null;
          }
  
          return [
              'username' =&gt; $request-&gt;request-&gt;get('_username'),
              'password' =&gt; $request-&gt;request-&gt;get('_password'),
          ];
      }
  
      /**
       * {@inheritdoc}
       * @param mixed                 $credentials
       * @param UserProviderInterface $userProvider
       *
       * @return CustomerAccount|null|UserInterface
       */
      public function getUser($credentials, UserProviderInterface $userProvider)
      {
          if (!$userProvider instanceof CustomerAccountUserProvider) {
              return null;
          }
  
          try {
              return $userProvider-&gt;loadUserByUsername($credentials['username']);
          } catch (UsernameNotFoundException $e) {
              throw new CustomUserMessageAuthenticationException($this-&gt;failMessage);
          }
      }
  
      /**
       * {@inheritdoc}
       * @param mixed         $credentials
       * @param UserInterface $user
       *
       * @return bool
       */
      public function checkCredentials($credentials, UserInterface $user)
      {
          $xml = $this-&gt;webservice-&gt;loginCustomerAccount([
              'username'         =&gt; $credentials['username'],
              'password'         =&gt; ($credentials['password']),
          ]);
  
          if (isset($xml-&gt;identification) &amp;&amp; isset($xml-&gt;identification['customer_id']) &amp;&amp; isset($xml-&gt;identification['id_token_session'])) {
              /** @var $user CustomerAccount */
              $user
                  -&gt;setIdTokenSession((string) $xml-&gt;identification['id_token_session'])
                  -&gt;setCustomerId((string) $xml-&gt;identification['customer_id'])
              ;
              return true;
          }
  
          throw new CustomUserMessageAuthenticationException($this-&gt;failMessage);
      }
  
      /**
       * {@inheritdoc}
       */
      public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey)
      {
          /** @var $user CustomerAccount */
          $user = $token-&gt;getUser();
  
          // Stockage en session, c'est ce qui maintient la connexion chez nous
          $this-&gt;session-&gt;clear();
          $this-&gt;session-&gt;set('customer_id', $user-&gt;getCustomerId());
          $this-&gt;session-&gt;set('id_token_session_customer', $user-&gt;getIdTokenSession());
          $this-&gt;session-&gt;set('login', $user-&gt;getUsername());
  
          // @todo LDA : adapter
          if ($this-&gt;session-&gt;has('_security.' . $providerKey . '.target_path')) {
              $url = $this-&gt;session-&gt;get('_security.' . $providerKey . '.target_path');
          } else {
              $url = $this-&gt;router-&gt;generate('customer_account_account');
          }
  
          return new RedirectResponse($url);
      }
  
      /**
       * {@inheritdoc}
       */
      public function onAuthenticationFailure(Request $request, AuthenticationException $exception)
      {
          $request-&gt;getSession()-&gt;set(Security::AUTHENTICATION_ERROR, $exception);
          $url = $this-&gt;router-&gt;generate('customer_account_login');
  
          return new RedirectResponse($url);
      }
  
      /**
       * {@inheritdoc}
       */
      public function start(Request $request, AuthenticationException $authException = null)
      {
          $url = $this-&gt;router-&gt;generate('customer_account_login');
  
          return new RedirectResponse($url);
      }
  
      /**
       * {@inheritdoc}
       */
      public function supportsRememberMe()
      {
          return false;
      }
  }
  </code></pre>