В моем api я пытаюсь аутентифицировать пользователя с помощью LdapИнструментыBundle, FOSUserBundle и LexikJWTAuthenticationBundle. Выполняя действия шаг за шагом и следуя документация по интеграции для fosuser и ldaptools и более поздним документам jwt, мне удается выполнить следующее:
проблема в том, что я могу войти только в свою базу данных, но не в ldap.
в моей базе данных есть одна пользовательская запись, которую я создал с помощью команды fos и любого пароля (чтобы убедиться, что аутентификация выполняется на ldap, а не на fosuser). Все идет нормально. но после установки JWT аутентификация выполняется fosuser вместо защиты аутентификации ldap. Когда я меняю пароль с помощью команды fos, я могу получить токен без проблем.
это мой конфиг:
security:
encoders:
FOS\UserBundle\Model\UserInterface: bcrypt
LdapTools\Bundle\LdapToolsBundle\Security\User\LdapUser: plaintext
role_hierarchy:
ROLE_ADMIN: ROLE_USER
ROLE_SUPER_ADMIN: ROLE_ADMIN
providers:
fos_userbundle:
id: fos_user.user_provider.username_email
ldap:
id: ldap_tools.security.user.ldap_user_provider
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
api_login:
pattern: ^/login
stateless: true
provider: fos_userbundle
anonymous: true
form_login:
check_path: /login
require_previous_session: false
username_parameter: username
password_parameter: password
success_handler: lexik_jwt_authentication.handler.authentication_success
failure_handler: lexik_jwt_authentication.handler.authentication_failure
require_previous_session: false
guard:
authenticators:
- ldap_tools.security.ldap_guard_authenticator
logout: true
api:
pattern: ^/
stateless: true
lexik_jwt: ~
access_control:
- { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/, role: IS_AUTHENTICATED_FULLY }
У меня вопрос, как мне заставить работать аутентификатор ldap? Я покажу нужный рабочий процесс
но я все еще получаю неверные учетные данные с зарегистрированным пользователем в базе данных и на сервере домена (учетные данные пользователя работают)
Заранее спасибо!




Покопайтесь в аутентификаторе ldap_tools.security.ldap_guard_authenticator (namespace LdapTools\Bundle\LdapToolsBundle\Security;) Я нашел это
public function getUser($credentials, UserProviderInterface $userProvider)
{
$domain = $this->ldap->getDomainContext();
try {
$credDomain = isset($credentials['ldap_domain']) ? $credentials['ldap_domain'] : '';
$this->switchDomainIfNeeded($credDomain);
$this->setLdapCredentialsIfNeeded($credentials['username'], $credentials['password'], $userProvider);
$user = $userProvider->loadUserByUsername($credentials['username']);
$this->userChecker->checkPreAuth($user);
return $user;
} catch (UsernameNotFoundException $e) {
$this->hideOrThrow($e, $this->options['hide_user_not_found_exceptions']);
} catch (BadCredentialsException $e) {
$this->hideOrThrow($e, $this->options['hide_user_not_found_exceptions']);
} catch (LdapConnectionException $e) {
$this->hideOrThrow($e, $this->options['hide_user_not_found_exceptions']);
} catch (\Exception $e) {
$this->hideOrThrow($e, $this->options['hide_user_not_found_exceptions']);
} finally {
$this->switchDomainBackIfNeeded($domain);
}
}
Этот метод загружает пользователя с указанием пользователя и некоторых учетных данных.
Итак, getUser полагается на userprovider для загрузки любого пользователя, но поскольку вы используете fos_userbundle в качестве userprovider для вашего брандмауэра api_login, вы фактически аутентифицируетесь в своей локальной базе данных. Попробуйте вместо этого использовать в своей конфигурации ldap userprovider.
Конечно, при этом вы будете аутентифицироваться на сервере ldap, а не в потоке, который вы описали выше. Для этого рассмотрите возможность самостоятельной обработки аутентификации, чтобы вы могли обрабатывать поток по своему усмотрению.
Также вы можете сделать это так
пользовательский аутентификатор и в вашем public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey)
вы можете проверить учетные данные на вашем сервере ldap с помощью службы "@ldap_tools.ldap_manager"->authenticate($user, $password, &$errorMessage = false, &$errorNumber = false).
Вот мой ответ: просто принудительно авторизуйтесь после проверки сервера ldap.
public function onAuthenticationFailure(AuthenticationFailureEvent $event)//when auth fails on DB(Allways!!!)
{
$userToken = $event->getAuthenticationToken();
$username = $userToken->getUsername();
$password = $this->requestStack->getCurrentRequest()->get('password');
if ($this->ldapManager->authenticate($username, $password)) {//good credentials
$token = new UsernamePasswordToken($userToken, 'yes', "public", $userToken->getRoles());
$this->container->get('security.token_storage')->setToken($token);//set a token
$event = new InteractiveLoginEvent($this->requestStack->getCurrentRequest(), $token); //dispatch the auth event
$event->stopPropagation();
$this->container->get('event_dispatcher')->dispatch(SecurityEvents::INTERACTIVE_LOGIN,$event);
}
//symfony takes care of the response
}
Пока это лучший ответ, который я нашел