我正在一个小型的symfony网站上,我需要LDAP身份验证。此外,在用户首次登录时,我需要在数据库中保留一个用户实体,以便将该用户实体链接到其他用户。
我设法通过使用自定义保护身份验证使其工作,该身份验证检查LDAP服务器以验证凭据。它还使用LdapUserProvider从LDAP信息生成User对象。
class LdapCustomAuthenticator extends AbstractFormLoginAuthenticator
{
use TargetPathTrait;
private $entityManager;
private $urlGenerator;
private $csrfTokenManager;
private $ldapUserProvider;
private $ldap;
public function __construct(EntityManagerInterface $entityManager, UrlGeneratorInterface $urlGenerator, CsrfTokenManagerInterface $csrfTokenManager, UserProviderInterface $ldapUserProvider, LdapInterface $ldap)
{
$this->entityManager = $entityManager;
$this->urlGenerator = $urlGenerator;
$this->csrfTokenManager = $csrfTokenManager;
$this->ldapUserProvider = $ldapUserProvider;
$this->ldap = $ldap;
}
public function supports(Request $request)
{
return 'app_login' === $request->attributes->get('_route')
&& $request->isMethod('POST');
}
public function getCredentials(Request $request)
{
$credentials = [
'username' => $request->request->get('_username'),
'password' => $request->request->get('_password'),
'csrf_token' => $request->request->get('_csrf_token'),
];
$request->getSession()->set(
Security::LAST_USERNAME,
$credentials['username']
);
return $credentials;
}
public function getUser($credentials, UserProviderInterface $userProvider)
{
$token = new CsrfToken('authenticate', $credentials['csrf_token']);
if (!$this->csrfTokenManager->isTokenValid($token)) {
throw new InvalidCsrfTokenException();
}
$ldapUser = $this->ldapUserProvider->loadUserByUsername($credentials['username']);
$localDBUser = $this->entityManager->getRepository(User::class)->findByUserName($credentials['username']);
if (! $localDBUser){
$this->entityManager->persist($ldapUser);
$this->entityManager->flush();
return $ldapUser;
}else{
$localDBUser->setDn($ldapUser->getDn());
return $localDBUser;
}
}
public function checkCredentials($credentials, UserInterface $user)
{
$username = $credentials['username'];
$password = $credentials['password'];
if ('' === (string) $password) {
throw new BadCredentialsException('The presented password must not be empty.');
}
try {
$this->ldap->bind($user->getDn(), $password);
return true;
} catch (ConnectionException $e) {
return false;
}
}
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('app_login');
}
}
我也在自定义LdapUserProvider,但是我跳过了细节。 但是在我的security.yaml中,我仍然使用EntityUserProvider:
security:
providers:
app_user_provider:
entity:
class: App\Entity\User
property: username
我的问题是在getUser方法的这些行中:
$ldapUser = $this->ldapUserProvider->loadUserByUsername($credentials['username']);
$localDBUser = $this->entityManager->getRepository(User::class)->findByUserName($credentials['username']);
if (! $localDBUser){
$this->entityManager->persist($ldapUser);
$this->entityManager->flush();
return $ldapUser;
}else{
$localDBUser->setDn($ldapUser->getDn());
return $localDBUser;
}
该方法不应在数据库中保存任何内容。但是由于我需要在用户首次登录时保留该用户,因此我看不到该代码在其他地方。
您有什么建议清理它?