title: Symfony 4 basic http authentication using user entity
body: <p>First of all i tryed the simple way with the in_memory provder like in this documentation: <a href="https://symfony.com/doc/current/security.html" rel="nofollow noreferrer">https://symfony.com/doc/current/security.html</a> and it worked for me well, then i continued with this tutorial: <a href="https://symfony.com/doc/current/security/entity_provider.html" rel="nofollow noreferrer">https://symfony.com/doc/current/security/entity_provider.html</a> and ended up in an endless loop of browser http basic user data request.</p>
  
  <p>This is my code, maybe someone can find the tiny missing semicolon :D</p>
  
  <p>URL: <a href="https://gitlab.com/AceVik/ajoli" rel="nofollow noreferrer">https://gitlab.com/AceVik/ajoli</a></p>
  
  <p>Neccessery files.
  security.yml</p>
  
  <pre><code>security:
  # https://symfony.com/doc/current/security.html#where-do-users-come-from-user-providers
  providers:
      our_db_provider:
           entity:
              class: App\Entity\User
      #        property: username
      #in_memory:
      #    memory:
      #        users:
      #            admin:
      #                password: admin
      #                roles: 'ROLE_ADMIN'
  firewalls:
      #secured_area:
      #    logout:
      #        path: /logout
      #        target: /
      dev:
          pattern: ^/(_(profiler|wdt)|css|images|js)/
          security: false
      main:
      #    pattern:    ^/
          http_basic: ~
          provider: our_db_provider
     #     provider: in_memory
  encoders:
      App\Entity\User: plaintext
      #    algorithm: bcrypt
      #    cost: 12
      #Symfony\Component\Security\Core\User\User: plaintext
  
  role_hierarchy:
      ROLE_ADMIN:       ROLE_USER
      ROLE_SUPER_ADMIN: [ROLE_USER, ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]
  
  # 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: ^/admin, roles: ROLE_ADMIN }
       - { path: ^/profile, roles: ROLE_USER }
  </code></pre>
  
  <p>User.php</p>
  
  <pre><code>&lt;?php
  
  declare(strict_types=1);
  
  namespace App\Entity;
  
  use Doctrine\ORM\Mapping as ORM;
  use Symfony\Component\Security\Core\User\UserInterface;
  
  /**
   * @ORM\Table(name="users")
   * @ORM\Entity(repositoryClass="App\Repository\UserRepository")
   */
  class User implements UserInterface, \Serializable
  {
      /**
       * @ORM\Column(type="integer")
       * @ORM\Id
       * @ORM\GeneratedValue(strategy="AUTO")
       */
      private $id;
  
      /**
       * @ORM\Column(type="string", length=25, unique=true)
       */
      private $username;
  
      /**
       * @ORM\Column(type="string", length=64)
       */
      private $password;
  
      /**
       * @ORM\Column(type="string", length=254, unique=true)
       */
      private $email;
  
      /**
       * @ORM\Column(name="is_active", type="boolean")
       */
      private $isActive;
  
      public function __construct()
      {
          $this-&gt;isActive = true;
          // may not be needed, see section on salt below
          // $this-&gt;salt = md5(uniqid('', true));
      }
  
      public function getUsername()
      {
          return $this-&gt;username;
      }
  
      public function setUsername($username) {
          $this-&gt;username = $username;
          $this-&gt;email = $username . '@example.com';
      }
  
      public function setPassword($password) {
          $this-&gt;password = $password;
      }
  
      public function getSalt()
      {
          // you *may* need a real salt depending on your encoder
          // see section on salt below
          return null;
      }
  
      public function getPassword()
      {
          return $this-&gt;password;
      }
  
      public function getRoles()
      {
          return array('ROLE_USER');
      }
  
      public function eraseCredentials()
      {
      }
  
      /** @see \Serializable::serialize() */
      public function serialize()
      {
          return serialize(array(
              $this-&gt;id,
              $this-&gt;username,
              $this-&gt;password,
              // see section on salt below
              // $this-&gt;salt,
          ));
      }
  
      /** @see \Serializable::unserialize() */
      public function unserialize($serialized)
      {
          list (
              $this-&gt;id,
              $this-&gt;username,
              $this-&gt;password,
              // see section on salt below
              // $this-&gt;salt
              ) = unserialize($serialized, ['allowed_classes' =&gt; false]);
      }
  }
  </code></pre>
  
  <p>UserRepository.php</p>
  
  <pre><code>&lt;?php
  
  namespace App\Repository;
  
  use App\Entity\User;
  use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
  use Doctrine\Common\Persistence\ManagerRegistry;
  use Symfony\Bridge\Doctrine\Security\User\UserLoaderInterface;
  
  class UserRepository extends ServiceEntityRepository implements UserLoaderInterface
  {
      public function __construct(ManagerRegistry $registry)
      {
          parent::__construct($registry, User::class);
      }
  
      public function loadUserByUsername($username)
      {
          return $this-&gt;createQueryBuilder('u')
              -&gt;where('u.username = :username')
              -&gt;setParameter('username', $username)
              -&gt;getQuery()
              -&gt;getOneOrNullResult();
      }
  }
  </code></pre>