title: Symfony 4 login form server authentication failed not working
body: <p>I've got a problem with my symfony 4 login form.
  I'm doing it in accordance with documentation: <a href="https://symfony.com/doc/current/security/form_login_setup.html" rel="nofollow noreferrer">https://symfony.com/doc/current/security/form_login_setup.html</a></p>
  
  <p>It's work fine then password and email correct, but <strong>nothing happens if email and/or password couldn't be find in database</strong></p>
  
  <p>My MainFormAuthentication:</p>
  
  <pre><code>&lt;?php
  
  namespace App\Security;
  
  use App\Entity\Users;
  use Doctrine\ORM\EntityManagerInterface;
  use Symfony\Component\HttpFoundation\RedirectResponse;
  use Symfony\Component\HttpFoundation\Request;
  use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
  use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
  use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
  use Symfony\Component\Security\Core\Exception\AuthenticationException;
  use Symfony\Component\Security\Core\Exception\CustomUserMessageAuthenticationException;
  use Symfony\Component\Security\Core\Exception\InvalidCsrfTokenException;
  use Symfony\Component\Security\Core\Security;
  use Symfony\Component\Security\Core\User\UserInterface;
  use Symfony\Component\Security\Core\User\UserProviderInterface;
  use Symfony\Component\Security\Csrf\CsrfToken;
  use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
  use Symfony\Component\Security\Guard\Authenticator\AbstractFormLoginAuthenticator;
  use Symfony\Component\Security\Http\Util\TargetPathTrait;
  
  class MainFormAuthenticator extends AbstractFormLoginAuthenticator
  {
      use TargetPathTrait;
  
      private $entityManager;
      private $urlGenerator;
      private $csrfTokenManager;
      private $passwordEncoder;
  
      public function __construct(EntityManagerInterface $entityManager, UrlGeneratorInterface $urlGenerator, CsrfTokenManagerInterface $csrfTokenManager, UserPasswordEncoderInterface $passwordEncoder)
      {
          $this-&gt;entityManager = $entityManager;
          $this-&gt;urlGenerator = $urlGenerator;
          $this-&gt;csrfTokenManager = $csrfTokenManager;
          $this-&gt;passwordEncoder = $passwordEncoder;
      }
  
      public function supports(Request $request)
      {
          return 'app_login' === $request-&gt;attributes-&gt;get('_route')
              &amp;&amp; $request-&gt;isMethod('POST');
      }
  
      public function getCredentials(Request $request)
      {
          $credentials = [
              'email' =&gt; $request-&gt;request-&gt;get('email'),
              'password' =&gt; $request-&gt;request-&gt;get('password'),
              'csrf_token' =&gt; $request-&gt;request-&gt;get('_csrf_token'),
          ];
          $request-&gt;getSession()-&gt;set(
              Security::LAST_USERNAME,
              $credentials['email']
          );
  
          return $credentials;
      }
  
      public function getUser($credentials, UserProviderInterface $userProvider)
      {
          $token = new CsrfToken('authenticate', $credentials['csrf_token']);
          if (!$this-&gt;csrfTokenManager-&gt;isTokenValid($token)) {
              throw new InvalidCsrfTokenException();
          }
  
          $user = $this-&gt;entityManager-&gt;getRepository(Users::class)-&gt;findOneBy(['email' =&gt; $credentials['email']]);
  
          if (!$user) {
              // fail authentication with a custom error
              throw new CustomUserMessageAuthenticationException('Email could not be found.');
          }
  
          return $user;
      }
      public function checkCredentials($credentials, UserInterface $user)
      {
           return $this-&gt;passwordEncoder-&gt;isPasswordValid($user, $credentials['password']);
      }
  
      public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey)
      {
          if ($targetPath = $this-&gt;getTargetPath($request-&gt;getSession(), $providerKey)) {
              return new RedirectResponse($targetPath);
          }
          return new RedirectResponse($this-&gt;urlGenerator-&gt;generate('dashboard'));
      }
  //    public function onAuthenticationFailure(Request $request, AuthenticationException $exception)
  //    {
  //        return $this-&gt;urlGenerator-&gt;generate('app_login');
  //    }
  
      protected function getLoginUrl()
      {
          return $this-&gt;urlGenerator-&gt;generate('app_login');
      }
  }
  </code></pre>
  
  <p>My MainSecurityController:</p>
  
  <pre><code>&lt;?php
  
  namespace App\Controller;
  
  use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  use Symfony\Component\HttpFoundation\Response;
  use Symfony\Component\Routing\Annotation\Route;
  use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
  
  class MainSecurityController extends AbstractController
  {
      /**
       * @Route("/login", name="app_login")
       */
      public function login(AuthenticationUtils $authenticationUtils): Response
      {
          // if ($this-&gt;getUser()) {
          //     return $this-&gt;redirectToRoute('target_path');
          // }
  
          // get the login error if there is one
          $error = $authenticationUtils-&gt;getLastAuthenticationError();
          // last username entered by the user
          $lastUsername = $authenticationUtils-&gt;getLastUsername();
  
          return $this-&gt;render('security/login.html.twig', ['last_username' =&gt; $lastUsername, 'error' =&gt; $error]);
      }
  
      /**
       * @Route("/logout", name="app_logout")
       */
      public function logout()
      {
          throw new \Exception('This method can be blank - it will be intercepted by the logout key on your firewall');
      }
  }
  </code></pre>
  
  <p>My LoginTwig: </p>
  
  <pre><code>{% extends 'main/main_layout.html.twig' %}
  
  {% block title %}Log in!{% endblock %}
  
  {% block leftcontent %}
      {{ dump(error) }}
  &lt;form method="post"&gt;
      {% if error %}
          &lt;div class="alert alert-danger"&gt;{{ error.messageKey|trans(error.messageData, 'security') }}&lt;/div&gt;
      {% endif %}
  
      {% if app.user %}
          &lt;div class="mb-3"&gt;
              You are logged in as {{ app.user.username }}, &lt;a href="{{ path('app_logout') }}"&gt;Logout&lt;/a&gt;
          &lt;/div&gt;
      {% endif %}
  
      &lt;h1 class="h3 mb-3 font-weight-normal"&gt;Please sign in&lt;/h1&gt;
      &lt;label for="inputEmail"&gt;Email&lt;/label&gt;
      &lt;input type="email" value="{{ last_username }}" name="email" id="inputEmail" class="form-control" required autofocus&gt;
      &lt;label for="inputPassword"&gt;Password&lt;/label&gt;
      &lt;input type="password" name="password" id="inputPassword" class="form-control" required&gt;
  
      &lt;input type="hidden" name="_csrf_token"
             value="{{ csrf_token('authenticate') }}"
      &gt;
  
      {#
          Uncomment this section and add a remember_me option below your firewall to activate remember me functionality.
          See https://symfony.com/doc/current/security/remember_me.html
  
          &lt;div class="checkbox mb-3"&gt;
              &lt;label&gt;
                  &lt;input type="checkbox" name="_remember_me"&gt; Remember me
              &lt;/label&gt;
          &lt;/div&gt;
      #}
  
      &lt;button class="btn btn-lg btn-primary" type="submit"&gt;
          Sign in
      &lt;/button&gt;
  &lt;/form&gt;
  {% endblock %}
  </code></pre>
  
  <p>My security.yaml:</p>
  
  <pre><code>security:
      encoders:
          App\Entity\Users:
              algorithm: auto
      # https://symfony.com/doc/current/security.html#where-do-users-come-from-user-providers
      providers:
          # used to reload user from session &amp; other features (e.g. switch_user)
          app_user_provider:
              entity:
                  class: App\Entity\Users
                  property: email
          # used to reload user from session &amp; other features (e.g. switch_user)
      firewalls:
          dev:
              pattern: ^/(_(profiler|wdt)|css|images|js)/
              security: false
          main:
              anonymous: true
  #            anonymous: ~
              guard:
                  authenticators:
  #                    - App\Security\LoginFormAuthenticator
                      - App\Security\MainFormAuthenticator
                  entry_point: App\Security\MainFormAuthenticator
              logout:
                  path: app_logout
                  # where to redirect after logout
                  target: app_login
  
              # activate different ways to authenticate
              # https://symfony.com/doc/current/security.html#firewalls-authentication
  
              # https://symfony.com/doc/current/security/impersonating_user.html
              # switch_user: true
  
      # Easy way to control access for large sections of your site
      # Note: Only the *first* access control that matches will be used
      access_control:
          - { path: ^/login$, roles: IS_AUTHENTICATED_ANONYMOUSLY }
          - { path: ^/dashboard/admin/, roles: ROLE_ADMIN }
          - { path: ^/dashboard/manager/, roles: ROLE_MANAGER }
          - { path: ^/dashboard/arendator/, roles: ROLE_ARENDATOR }
          - { path: ^/dashboard/user/, roles: ROLE_USER }
          # may be yes, may be no...
          - { path: ^/api$, roles: IS_AUTHENTICATED_ANONYMOUSLY }
  </code></pre>
  
  <p><strong>First edit</strong></p>
  
  <p>Made changes in <strong>security.yaml</strong>, but it still does not work:</p>
  
  <pre><code>security:
      encoders:
          App\Entity\Users:
              algorithm: auto
      # https://symfony.com/doc/current/security.html#where-do-users-come-from-user-providers
      providers:
          # used to reload user from session &amp; other features (e.g. switch_user)
          app_user_provider:
              entity:
                  class: App\Entity\Users
                  property: email
          # used to reload user from session &amp; other features (e.g. switch_user)
      firewalls:
          dev:
              pattern: ^/(_(profiler|wdt)|css|images|js)/
              security: false
          main:
              anonymous: true
  #            anonymous: ~
              guard: # delete entry_point, and left only one authenticator in guard:
                  authenticators:
                      - App\Security\MainFormAuthenticator
              logout:
                  path: app_logout
                  # where to redirect after logout
                  target: app_login
  
              # activate different ways to authenticate
              # https://symfony.com/doc/current/security.html#firewalls-authentication
  
              # https://symfony.com/doc/current/security/impersonating_user.html
              # switch_user: true
  
      # Easy way to control access for large sections of your site
      # Note: Only the *first* access control that matches will be used
      access_control:
          - { path: ^/login$, roles: IS_AUTHENTICATED_ANONYMOUSLY }
          - { path: ^/dashboard/admin/, roles: ROLE_ADMIN }
          - { path: ^/dashboard/manager/, roles: ROLE_MANAGER }
          - { path: ^/dashboard/arendator/, roles: ROLE_ARENDATOR }
          - { path: ^/dashboard/user/, roles: ROLE_USER }
          # may be yes, may be no...
          - { path: ^/api$, roles: IS_AUTHENTICATED_ANONYMOUSLY }
  </code></pre>
  
  <p><strong>This is what happened in logs then authentication failed:</strong></p>
  
  <pre><code>[2020-01-19 17:11:57] request.INFO: Matched route "app_login". {"route":"app_login","route_parameters":{"_route":"app_login","_controller":"App\\Controller\\MainSecurityController::login"},"request_uri":"http://127.0.0.1:8000/login","method":"POST"} []
  [2020-01-19 17:11:57] php.INFO: User Deprecated: Creating Doctrine\ORM\Mapping\UnderscoreNamingStrategy without making it number aware is deprecated and will be removed in Doctrine ORM 3.0. {"exception":"[object] (ErrorException(code: 0): User Deprecated: Creating Doctrine\\ORM\\Mapping\\UnderscoreNamingStrategy without making it number aware is deprecated and will be removed in Doctrine ORM 3.0. at C:\\Users\\andre\\Desktop\\Git_Projects\\openserver\\OSPanel\\domains\\parkingapp\\vendor\\doctrine\\orm\\lib\\Doctrine\\ORM\\Mapping\\UnderscoreNamingStrategy.php:66)"} []
  [2020-01-19 17:11:57] security.DEBUG: Checking for guard authentication credentials. {"firewall_key":"main","authenticators":1} []
  [2020-01-19 17:11:57] security.DEBUG: Checking support on guard authenticator. {"firewall_key":"main","authenticator":"App\\Security\\MainFormAuthenticator"} []
  [2020-01-19 17:11:57] security.DEBUG: Calling getCredentials() on guard authenticator. {"firewall_key":"main","authenticator":"App\\Security\\MainFormAuthenticator"} []
  [2020-01-19 17:11:57] security.DEBUG: Passing guard token information to the GuardAuthenticationProvider {"firewall_key":"main","authenticator":"App\\Security\\MainFormAuthenticator"} []
  [2020-01-19 17:11:58] doctrine.DEBUG: SELECT t0.id AS id_1, t0.email AS email_2, t0.roles AS roles_3, t0.password AS password_4, t0.user_login AS user_login_5, t0.user_block_state AS user_block_state_6, t0.user_date_create AS user_date_create_7 FROM users t0 WHERE t0.email = ? LIMIT 1 ["adminmail123@gmail.com"] []
  [2020-01-19 17:12:00] security.INFO: Guard authentication failed. {"exception":"[object] (Symfony\\Component\\Security\\Core\\Exception\\BadCredentialsException(code: 0): Authentication failed because App\\Security\\MainFormAuthenticator::checkCredentials() did not return true. at C:\\Users\\andre\\Desktop\\Git_Projects\\openserver\\OSPanel\\domains\\parkingapp\\vendor\\symfony\\security-guard\\Provider\\GuardAuthenticationProvider.php:113)","authenticator":"App\\Security\\MainFormAuthenticator"} []
  [2020-01-19 17:12:00] security.DEBUG: The "App\Security\MainFormAuthenticator" authenticator set the response. Any later authenticator will not be called {"authenticator":"App\\Security\\MainFormAuthenticator"} []
  [2020-01-19 17:12:02] request.INFO: Matched route "app_login". {"route":"app_login","route_parameters":{"_route":"app_login","_controller":"App\\Controller\\MainSecurityController::login"},"request_uri":"http://127.0.0.1:8000/login","method":"GET"} []
  [2020-01-19 17:12:02] php.INFO: User Deprecated: Creating Doctrine\ORM\Mapping\UnderscoreNamingStrategy without making it number aware is deprecated and will be removed in Doctrine ORM 3.0. {"exception":"[object] (ErrorException(code: 0): User Deprecated: Creating Doctrine\\ORM\\Mapping\\UnderscoreNamingStrategy without making it number aware is deprecated and will be removed in Doctrine ORM 3.0. at C:\\Users\\andre\\Desktop\\Git_Projects\\openserver\\OSPanel\\domains\\parkingapp\\vendor\\doctrine\\orm\\lib\\Doctrine\\ORM\\Mapping\\UnderscoreNamingStrategy.php:66)"} []
  [2020-01-19 17:12:02] security.DEBUG: Checking for guard authentication credentials. {"firewall_key":"main","authenticators":1} []
  [2020-01-19 17:12:02] security.DEBUG: Checking support on guard authenticator. {"firewall_key":"main","authenticator":"App\\Security\\MainFormAuthenticator"} []
  [2020-01-19 17:12:02] security.DEBUG: Guard authenticator does not support the request. {"firewall_key":"main","authenticator":"App\\Security\\MainFormAuthenticator"} []
  [2020-01-19 17:12:02] security.INFO: Populated the TokenStorage with an anonymous Token. [] []
  </code></pre>
  
  <p>My Users Entity Class:</p>
  
  <pre><code>&lt;?php
  
  namespace App\Entity;
  
  use Doctrine\Common\Collections\ArrayCollection;
  use Doctrine\Common\Collections\Collection;
  use Doctrine\ORM\Mapping as ORM;
  use Symfony\Component\Security\Core\User\UserInterface;
  
  /**
   * @ORM\Entity(repositoryClass="App\Repository\UsersRepository")
   */
  class Users implements UserInterface
  {
      /**
       * @ORM\Id()
       * @ORM\GeneratedValue()
       * @ORM\Column(type="integer")
       */
      private $id;
  
      /**
       * @ORM\Column(type="string", length=180, unique=true)
       */
      private $email;
  
      /**
       * @ORM\Column(type="json")
       */
      private $roles = [];
  
      /**
       * @var string The hashed password
       * @ORM\Column(type="string")
       */
      private $password;
  
      /**
       * @ORM\Column(type="string", length=100)
       */
      private $userLogin;
  
      /**
       * @ORM\Column(type="boolean")
       */
      private $userBlockState;
  
      /**
       * @ORM\Column(type="datetime")
       */
      private $userDateCreate;
  
      /**
       * @ORM\OneToMany(targetEntity="App\Entity\UserCards", mappedBy="this_user")
       */
      private $userCards;
  
      /**
       * @ORM\OneToMany(targetEntity="App\Entity\Transactions", mappedBy="this_user")
       */
      private $transactions;
  
      /**
       * @ORM\ManyToMany(targetEntity="App\Entity\Parkings", inversedBy="linkedusers")
       */
      private $linkedparkings;
  
  //    /**
  //     * @ORM\ManyToMany(targetEntity="App\Entity\Parkings", inversedBy="linkeduser")
  //     */
  //    private $linkedparkings;
  //
  //    /**
  //     * @ORM\ManyToMany(targetEntity="App\Entity\Parkings", mappedBy="has_user")
  //     */
  //    private $has_parking;
  
      public function __construct()
      {
          $this-&gt;userCards = new ArrayCollection();
          $this-&gt;transactions = new ArrayCollection();
  //        $this-&gt;linkedparkings = new ArrayCollection();
  //        $this-&gt;has_parking = new ArrayCollection();
      }
  
      public function getId(): ?int
      {
          return $this-&gt;id;
      }
  
      public function getEmail(): ?string
      {
          return $this-&gt;email;
      }
  
      public function setEmail(string $email): self
      {
          $this-&gt;email = $email;
  
          return $this;
      }
  
      /**
       * A visual identifier that represents this user.
       *
       * @see UserInterface
       */
      public function getUsername(): string
      {
          return (string) $this-&gt;email;
      }
  
      /**
       * @see UserInterface
       */
      public function getRoles(): array
      {
          $roles = $this-&gt;roles;
          // guarantee every user at least has ROLE_USER
          $roles[] = 'ROLE_USER';
  
          return array_unique($roles);
      }
  
      public function setRoles(array $roles): self
      {
          $this-&gt;roles = $roles;
  
          return $this;
      }
  
      /**
       * @see UserInterface
       */
      public function getPassword(): string
      {
          return (string) $this-&gt;password;
      }
  
      public function setPassword(string $password): self
      {
          $this-&gt;password = $password;
  
          return $this;
      }
  
      /**
       * @see UserInterface
       */
      public function getSalt()
      {
          // not needed when using the "bcrypt" algorithm in security.yaml
      }
  
      /**
       * @see UserInterface
       */
      public function eraseCredentials()
      {
          // If you store any temporary, sensitive data on the user, clear it here
          // $this-&gt;plainPassword = null;
      }
  
      public function getUserLogin(): ?string
      {
          return $this-&gt;userLogin;
      }
  
      public function setUserLogin(string $userLogin): self
      {
          $this-&gt;userLogin = $userLogin;
  
          return $this;
      }
  
      public function getUserBlockState(): ?bool
      {
          return $this-&gt;userBlockState;
      }
  
      public function setUserBlockState(bool $userBlockState): self
      {
          $this-&gt;userBlockState = $userBlockState;
  
          return $this;
      }
  
      public function getUserDateCreate(): ?\DateTimeInterface
      {
          return $this-&gt;userDateCreate;
      }
  
      public function setUserDateCreate(\DateTimeInterface $userDateCreate): self
      {
          $this-&gt;userDateCreate = $userDateCreate;
  
          return $this;
      }
  
      /**
       * @return Collection|UserCards[]
       */
      public function getUserCards(): Collection
      {
          return $this-&gt;userCards;
      }
  
      public function addUserCard(UserCards $userCard): self
      {
          if (!$this-&gt;userCards-&gt;contains($userCard)) {
              $this-&gt;userCards[] = $userCard;
              $userCard-&gt;setThisUser($this);
          }
  
          return $this;
      }
  
      public function removeUserCard(UserCards $userCard): self
      {
          if ($this-&gt;userCards-&gt;contains($userCard)) {
              $this-&gt;userCards-&gt;removeElement($userCard);
              // set the owning side to null (unless already changed)
              if ($userCard-&gt;getThisUser() === $this) {
                  $userCard-&gt;setThisUser(null);
              }
          }
  
          return $this;
      }
  
      /**
       * @return Collection|Transactions[]
       */
      public function getTransactions(): Collection
      {
          return $this-&gt;transactions;
      }
  
      public function addTransaction(Transactions $transaction): self
      {
          if (!$this-&gt;transactions-&gt;contains($transaction)) {
              $this-&gt;transactions[] = $transaction;
              $transaction-&gt;setThisUser($this);
          }
  
          return $this;
      }
  
      public function removeTransaction(Transactions $transaction): self
      {
          if ($this-&gt;transactions-&gt;contains($transaction)) {
              $this-&gt;transactions-&gt;removeElement($transaction);
              // set the owning side to null (unless already changed)
              if ($transaction-&gt;getThisUser() === $this) {
                  $transaction-&gt;setThisUser(null);
              }
          }
  
          return $this;
      }
  
      /**
       * @return Collection|Parkings[]
       */
      public function getLinkedparkings(): Collection
      {
          return $this-&gt;linkedparkings;
      }
  
      public function addLinkedparking(Parkings $linkedparking): self
      {
          if (!$this-&gt;linkedparkings-&gt;contains($linkedparking)) {
              $this-&gt;linkedparkings[] = $linkedparking;
          }
  
          return $this;
      }
  
      public function removeLinkedparking(Parkings $linkedparking): self
      {
          if ($this-&gt;linkedparkings-&gt;contains($linkedparking)) {
              $this-&gt;linkedparkings-&gt;removeElement($linkedparking);
          }
  
          return $this;
      }
  
  //    /**
  //     * @return Collection|Parkings[]
  //     */
  //    public function getLinkedparkings(): Collection
  //    {
  //        return $this-&gt;linkedparkings;
  //    }
  //
  //    public function addLinkedparking(Parkings $linkedparking): self
  //    {
  //        if (!$this-&gt;linkedparkings-&gt;contains($linkedparking)) {
  //            $this-&gt;linkedparkings[] = $linkedparking;
  //        }
  //
  //        return $this;
  //    }
  //
  //    public function removeLinkedparking(Parkings $linkedparking): self
  //    {
  //        if ($this-&gt;linkedparkings-&gt;contains($linkedparking)) {
  //            $this-&gt;linkedparkings-&gt;removeElement($linkedparking);
  //        }
  //
  //        return $this;
  //    }
  //
  //    /**
  //     * @return Collection|Parkings[]
  //     */
  //    public function getHasParking(): Collection
  //    {
  //        return $this-&gt;has_parking;
  //    }
  //
  //    public function addHasParking(Parkings $hasParking): self
  //    {
  //        if (!$this-&gt;has_parking-&gt;contains($hasParking)) {
  //            $this-&gt;has_parking[] = $hasParking;
  //            $hasParking-&gt;addHasUser($this);
  //        }
  //
  //        return $this;
  //    }
  //
  //    public function removeHasParking(Parkings $hasParking): self
  //    {
  //        if ($this-&gt;has_parking-&gt;contains($hasParking)) {
  //            $this-&gt;has_parking-&gt;removeElement($hasParking);
  //            $hasParking-&gt;removeHasUser($this);
  //        }
  //
  //        return $this;
  //    }
  }
  </code></pre>
  
  <p>Maybe someone has already faced a problem?</p>