Search code examples
phpnamespacesdoctrinesymfony4

The class 'App\Entity\Users' was not found in the chain configured namespaces


I want to add an Authentication system with Symfony 4. I'm using an Mssql Database, which is already created and populated.

This is not the first time, I'm using it. But this is the first time I have issues.

I imported all my entities, from my database, especially the Users Entity.

I also configurated LoginFormAuthenticator.php, and my security.yml

Users.php content:

<?php

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\User\UserInterface;

/**
 * Users
 *
 * @ORM\Table(name="USERS")
 * @ORM\Entity(repositoryClass=UsersRepository::class)
 */
class Users implements UserInterface
{
    /**
     * @var int
     *
     * @ORM\Column(name="US_ID", type="integer", nullable=false)
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $usId;

    /**
     * @var string|null
     *
     * @ORM\Column(name="US_PRENOM", type="string", length=50, nullable=true)
     */
    private $usPrenom;

    /**
     * @var string|null
     *
     * @ORM\Column(name="US_NOM", type="string", length=50, nullable=true)
     */
    private $usNom;

    /**
     * @var string|null
     *
     * @ORM\Column(name="US_MAIL", type="string", length=100, nullable=true)
     */
    private $usMail;

    /**
     * @var string|null
     *
     * @ORM\Column(name="US_PASS", type="string", length=50, nullable=true)
     */
    private $usPass;

    /**
     * @var int|null
     *
     * @ORM\Column(name="US_NIVEAU", type="integer", nullable=true)
     */
    private $usNiveau;

    /**
     * @var \DateTime|null
     *
     * @ORM\Column(name="INS_DATE", type="datetime", nullable=true)
     */
    private $insDate;

    /**
     * @var string|null
     *
     * @ORM\Column(name="INS_USER", type="string", length=100, nullable=true)
     */
    private $insUser;

    /**
     * @var \DateTime|null
     *
     * @ORM\Column(name="MAJ_DATE", type="datetime", nullable=true)
     */
    private $majDate;

    /**
     * @var string|null
     *
     * @ORM\Column(name="MAJ_USER", type="string", length=100, nullable=true)
     */
    private $majUser;

    /**
     * @return int
     */
    public function getUsId(): int
    {
        return $this->usId;
    }

    /**
     * @param int $usId
     */
    public function setUsId(int $usId): void
    {
        $this->usId = $usId;
    }

    /**
     * @return string|null
     */
    public function getUsPrenom(): ?string
    {
        return $this->usPrenom;
    }

    /**
     * @param string|null $usPrenom
     */
    public function setUsPrenom(?string $usPrenom): void
    {
        $this->usPrenom = $usPrenom;
    }

    /**
     * @return string|null
     */
    public function getUsNom(): ?string
    {
        return $this->usNom;
    }

    /**
     * @param string|null $usNom
     */
    public function setUsNom(?string $usNom): void
    {
        $this->usNom = $usNom;
    }

    /**
     * @return string|null
     */
    public function getUsMail(): ?string
    {
        return $this->usMail;
    }

    /**
     * @param string|null $usMail
     */
    public function setUsMail(?string $usMail): void
    {
        $this->usMail = $usMail;
    }

    /**
     * @return string|null
     */
    public function getUsPass(): ?string
    {
        return $this->usPass;
    }

    /**
     * @param string|null $usPass
     */
    public function setUsPass(?string $usPass): void
    {
        $this->usPass = $usPass;
    }

    /**
     * @return int|null
     */
    public function getUsNiveau(): ?int
    {
        return $this->usNiveau;
    }

    /**
     * @param int|null $usNiveau
     */
    public function setUsNiveau(?int $usNiveau): void
    {
        $this->usNiveau = $usNiveau;
    }

    /**
     * @return \DateTime|null
     */
    public function getInsDate(): ?\DateTime
    {
        return $this->insDate;
    }

    /**
     * @param \DateTime|null $insDate
     */
    public function setInsDate(?\DateTime $insDate): void
    {
        $this->insDate = $insDate;
    }

    /**
     * @return string|null
     */
    public function getInsUser(): ?string
    {
        return $this->insUser;
    }

    /**
     * @param string|null $insUser
     */
    public function setInsUser(?string $insUser): void
    {
        $this->insUser = $insUser;
    }

    /**
     * @return \DateTime|null
     */
    public function getMajDate(): ?\DateTime
    {
        return $this->majDate;
    }

    /**
     * @param \DateTime|null $majDate
     */
    public function setMajDate(?\DateTime $majDate): void
    {
        $this->majDate = $majDate;
    }

    /**
     * @return string|null
     */
    public function getMajUser(): ?string
    {
        return $this->majUser;
    }

    /**
     * @param string|null $majUser
     */
    public function setMajUser(?string $majUser): void
    {
        $this->majUser = $majUser;
    }

    /**
     * Returns the roles granted to the user.
     *
     *     public function getRoles()
     *     {
     *         return ['ROLE_USER'];
     *     }
     *
     * Alternatively, the roles might be stored on a ``roles`` property,
     * and populated in any number of different ways when the user object
     * is created.
     *
     * @return (Role|string)[] The user roles
     */
    public function getRoles()
    {
        return ['ROLE_USER'];
    }

    /**
     * Returns the password used to authenticate the user.
     *
     * This should be the encoded password. On authentication, a plain-text
     * password will be salted, encoded, and then compared to this value.
     *
     * @return string The password
     */
    public function getPassword()
    {
        return $this->getUsPass();
    }

    /**
     * Returns the salt that was originally used to encode the password.
     *
     * This can return null if the password was not encoded using a salt.
     *
     * @return string|null The salt
     */
    public function getSalt()
    {
        // TODO: Implement getSalt() method.
    }

    /**
     * Returns the username used to authenticate the user.
     *
     * @return string The username
     */
    public function getUsername()
    {

        return $this->getUsMail();
    }

    /**
     * Removes sensitive data from the user.
     *
     * This is important if, at any given point, sensitive information like
     * the plain-text password is stored on this object.
     */
    public function eraseCredentials()
    {
        // TODO: Implement eraseCredentials() method.
    }
}

LoginFormAuthenticator.php contents:

<?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\Exception\CustomUserMessageAuthenticationException;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
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 LoginFormAuthenticator extends AbstractFormLoginAuthenticator
{
    use TargetPathTrait;

    private $urlGenerator;
    private $csrfTokenManager;
    private $passwordEncoder;
    private $entityManager;

    public function __construct(EntityManagerInterface $entityManager,UrlGeneratorInterface $urlGenerator, CsrfTokenManagerInterface $csrfTokenManager, UserPasswordEncoderInterface $passwordEncoder)
    {
        $this->urlGenerator = $urlGenerator;
        $this->csrfTokenManager = $csrfTokenManager;
        $this->passwordEncoder = $passwordEncoder;
        $this->entityManager = $entityManager;

    }

    public function supports(Request $request)
    {
        return 'app_login' === $request->attributes->get('_route')
            && $request->isMethod('POST');
    }

    public function getCredentials(Request $request)
    {
        $credentials = [
            'usMail' => $request->request->get('usMail'),
            'password' => $request->request->get('password'),
            'csrf_token' => $request->request->get('_csrf_token'),
        ];
        $request->getSession()->set(
            Security::LAST_USERNAME,
            $credentials['usMail']
        );

        return $credentials;
    }

    public function getUser($credentials, UserProviderInterface $userProvider )
    {
        $token = new CsrfToken('authenticate', $credentials['csrf_token']);
        if (!$this->csrfTokenManager->isTokenValid($token)) {
            throw new InvalidCsrfTokenException();
        }

        // Load / create our user however you need.
        // You can do this by calling the user provider, or with custom logic here.
        $user = $this->entityManager->getRepository(Users::class)->findOneBy(['usMail' => $credentials['usMail']]);


        if (!$user) {
            // fail authentication with a custom error
            throw new CustomUserMessageAuthenticationException('UsMail could not be found.');
        }

        return $user;
    }

    public function checkCredentials($credentials, UserInterface $user)
    {
        return $this->passwordEncoder->isPasswordValid($user, $credentials['password']);
    }

    public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey)
    {
        if ($targetPath = $this->getTargetPath($request->getSession(), $providerKey)) {
            return new RedirectResponse($targetPath);
        }

        return new RedirectResponse($this->urlGenerator->generate('home'));
    }

    protected function getLoginUrl()
    {
        return $this->urlGenerator->generate('login');
    }
}

Security.yml content:

security:
    encoders:
        App\Entity\Users:
            algorithm:            plaintext
            ignore_case:          false

    role_hierarchy:
        ROLE_ADMIN:       ROLE_USER
        ROLE_SUPER_ADMIN: ROLE_ADMIN

    providers:
        users:
            entity:
                # the class of the entity that represents users
                class: 'App\Entity\Users'
                # the property to query by - e.g. username, email, etc
                property: 'usMail'
                # optional: if you're using multiple Doctrine entity
                # managers, this option defines which one to use
                # manager_name: 'customer'

    firewalls:
        main:
            pattern: ^/
            logout:
                invalidate_session: true
                path: /logout
                target: /login
            anonymous:    true
            guard:
                authenticators:
                    - App\Security\LoginFormAuthenticator

When I tried to login I have an exception

The class 'App\Entity\Users' was not found in the chain configured namespaces

Solution

  • There was an issue with the directory of the namespaces.

    If you use multi EntityManager you have to configure your doctrine.yaml like this:

    doctrine:
    dbal:
        default_connection:
        connections:
    
    orm:
        auto_generate_proxy_classes: '%kernel.debug%'
        naming_strategy: doctrine.orm.naming_strategy.underscore
        auto_mapping: true
        mappings:
            App:
                is_bundle: false
                type: annotation
                dir: '%kernel.project_dir%/src/Entity'
                prefix: 'App\Entity'
                alias: App