ldapManager = $ldapManager; $this->config = $config; $this->userProvider = $userProvider; } protected function retrieveUser($username, UsernamePasswordToken $token) { $user = $token->getUser(); if ($user instanceof UserInterface) { return $user; } try { // this will always query the FOSUserBundle first... // only first-time logins from LDAP user (not yet existing in local user database) // will actually hit the LdapUserProvider $user = $this->userProvider->loadUserByUsername($username); // do not update the user here from LDAP, as we don't know if the user can be authenticated } catch (UsernameNotFoundException $notFound) { throw $notFound; } catch (\Exception $repositoryProblem) { $e = new AuthenticationServiceException($repositoryProblem->getMessage(), (int) $repositoryProblem->getCode(), $repositoryProblem); $e->setToken($token); throw $e; } return $user; } /** * The updateUser() call should theoretically happen in retrieveUser() but that would require an additional * $this->ldapManager->bind($user, $token->getCredentials()) * to check if the user is still valid. * * Symfony calls retrieveUser() before checkAuthentication() * and we should not used ldap->search() before ldap->bind() * * @param UserInterface $user * @param UsernamePasswordToken $token * @throws LdapDriverException */ protected function checkAuthentication(UserInterface $user, UsernamePasswordToken $token) { $currentUser = $token->getUser(); $presentedPassword = $token->getCredentials(); if ($currentUser instanceof UserInterface) { if ('' === $presentedPassword) { throw new BadCredentialsException( 'The password in the token is empty. Check `erase_credentials` in your `security.yaml`' ); } if (!$this->ldapManager->bind($currentUser, $presentedPassword)) { throw new BadCredentialsException('The credentials were changed from another session.'); } } else { if ('' === $presentedPassword) { throw new BadCredentialsException('The presented password cannot be empty.'); } if (!$this->ldapManager->bind($user, $presentedPassword)) { throw new BadCredentialsException('The presented password is invalid.'); } } if ($user instanceof User && null !== $user->getPreferenceValue('ldap.dn')) { try { $this->ldapManager->updateUser($user); } catch (LdapDriverException $ex) { throw new BadCredentialsException('Fetching user data/roles failed, probably DN is expired.'); } } } }