src/Security/SecurityLdapFormAuthenticator.php line 41
<?phpnamespace App\Security;use Symfony\Component\HttpFoundation\RedirectResponse;use Symfony\Component\HttpFoundation\Request;use Symfony\Component\HttpFoundation\Response;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\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\Http\Authenticator\AbstractLoginFormAuthenticator;use Symfony\Component\Security\Http\Authenticator\Passport\Badge\CsrfTokenBadge;use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge;use Symfony\Component\Security\Http\Authenticator\Passport\Credentials\PasswordCredentials;use Symfony\Component\Security\Http\Authenticator\Passport\Credentials\CustomCredentials;use Symfony\Component\Security\Http\Authenticator\Passport\Passport;use Symfony\Component\Security\Http\Util\TargetPathTrait;use Symfony\Component\Security\Http\SecurityRequestAttributes;use Symfony\Component\Ldap\Ldap;use Symfony\Component\Ldap\LdapInterface;use Symfony\Component\Ldap\Adapter\QueryInterface;use Symfony\Component\Security\Core\Exception\UnsupportedUserException;use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;use Symfony\Component\Security\Core\Exception\LockedException;use Symfony\Component\Security\Core\Exception\AuthenticationException;use App\Repository\UserRepository;use App\Entity\User;use Symfony\Component\Ldap\Exception\InvalidCredentialsException;use Symfony\Component\Ldap\Exception\InvalidSearchCredentialsException;class SecurityLdapFormAuthenticator extends AbstractLoginFormAuthenticator{use TargetPathTrait;private UrlGeneratorInterface $urlGenerator;private CsrfTokenManagerInterface $csrfTokenManager;public function __construct(UrlGeneratorInterface $urlGenerator, CsrfTokenManagerInterface $csrfTokenManager){$this->urlGenerator = $urlGenerator;$this->csrfTokenManager = $csrfTokenManager;}protected function getLoginUrl(Request $request): string{return $this->urlGenerator->generate('security_ldap_login');}public function supports(Request $request): bool{return 'security_ldap_login' === $request->attributes->get('_route') && $request->isMethod('POST');}public function getCredentials(Request $request): array{$credentials = ['username' => $request->request->get('_username'),'password' => $request->request->get('_password'),'csrf_token' => $request->request->get('_csrf_token'),];$credentials['username'] = trim($credentials['username']);$request->getSession()->set(SecurityRequestAttributes::LAST_USERNAME,$credentials['username']);return $credentials;}public function checkCredentials($credentials, UserInterface $user): bool{// In this scenario, this method is by-passed since user authentication need to be managed before in getUser method.return true;}public function onAuthenticationSuccess(Request $request,TokenInterface $token,string $firewallName): ?Response {// $providerKey = $firewallName$request->getSession()->getFlashBag()->add('info', 'connected!');if ($targetPath = $this->getTargetPath($request->getSession(), $firewallName)) {return new RedirectResponse($targetPath);}return new RedirectResponse($this->urlGenerator->generate('home'));}public function authenticate(Request $request): Passport{$credentials = $this->getCredentials($request);$userBadge = new UserBadge($credentials["username"]);$customCredentials = new CustomCredentials(function($credentials, UserInterface $user) {if ($credentials["username"] && $credentials["password"]&& strtoupper($user->getUserIdentifier()) === strtoupper($credentials["username"])&& $this->getUserEntityCheckedFromLdap($credentials["username"], $credentials["password"], $user) !== NULL) {return true;}return false;},$credentials);$passport = new Passport($userBadge, $customCredentials, [new CsrfTokenBadge('authenticate', $request->request->get('_csrf_token'))]);return ($passport);}/*** search user against ldap and returns the matching App\Entity\User. The $user entity will be created if not exists.* @param string $username* @param string $password* @return User|object|null*/public function getUserEntityCheckedFromLdap(string $username, string $password, User $user){$ldapSearchDn = $_ENV["LDAP_USER"];$ldapSearchPassword = $_ENV["LDAP_PASS"];$ldapSearchDnString = $_ENV["LDAP_DN"];$server = $_ENV["LDAP_SERVER"];$ldap = Ldap::create('ext_ldap',['host' => $server,'encryption' => 'tls','version' => '3','referrals' => false,'options' => ['debug_level' => 7, 'x_tls_require_cert' => 'never'],]);try {$ldap->bind($ldapSearchDn, $ldapSearchPassword);} catch (InvalidCredentialsException) {throw new InvalidSearchCredentialsException();}$username = $ldap->escape($username, '', LdapInterface::ESCAPE_FILTER);$search = $ldap->query($ldapSearchDnString, "(sAMAccountName=" . $username . ")", ['scope' => QueryInterface::SCOPE_SUB]);$entries = $search->execute()->toArray();$count = count($entries);if (!$count) {throw new AuthenticationException(sprintf('User "%s" not found.', $username));}if ($count > 1) {throw new AuthenticationException('More than one user found');}$ldapEntry = $entries[0];$dn = $ldapEntry->getDn();try {$ldap->bind($dn, $password);} catch (InvalidCredentialsException) {throw new AuthenticationException('Credentials Invalid');}//Si l'utilisateur n'existe pas en DBif (!$user)throw new AuthenticationException("User doesn't exist on ENSO");//S'il existe, on récupère l'employee$employee = $user->getEmployee();if (!$employee)throw new LockedException();return $user;}}