Во-первых, извините за мой английский и английский google-translate:)
На русском: https://ru.stackoverflow.com/questions/1031596/symfony-4-Авторизация-через-ldap-Как-подключить-кастомный-authenticationprovid
Моя проблема в том, что мой LDAP-сервер делает авторизацию исключительно на dn, полученном от Entry послепоиск. То есть он ищет по имени пользователя:
$query: (samAccountName=AIvanov)
, но авторизуется только по атрибуту dn:
$dn: CN=Ivanov Alxey,OU=Staff,OU=Users,OU=Company,DC=company,DC=local
И если есть способ, как использовать конфигурацию, чтобы указать способперенести из пользовательского UserProvider в нативные данные LdapBindAuthenticationProvider, которые вам нужно использовать, не имя пользователя из токена, а взять имя пользователя из объекта этого пользовательского пользователя:
$user->getUsername()
, который вернет эти проклятые имя и фамилию, ябуду благодарен. Потому что в противном случае только создание CustomLdapBindAuthenticationProvider, с которым я пришел сюда.
Использовал руководство: https://symfony.com/doc/current/security/custom_authentication_provider.html
И я остановился на том факте, что не знаю, какова связь между моимфабрика и брандмауэр, и у меня есть ошибка при вызове этой фабрики.
Итак, следуя этому руководству, я создал пользовательский поставщик аутентификации. Я пытался унаследовать от нативного Ldap ... но его свойство ldap является частным, поэтому я просто скопировал весь Ldap себе и переименовал его в CustomLdapBindAuthenticationProvider. Поменял там эту одну строчку, из-за которой вся суета. Затем я создал его собственную фабрику, унаследовав ее от родного FormLoginLdapFactory
class CustomFormLoginLdapFactory extends FormLoginLdapFactory {
protected function createAuthProvider(ContainerBuilder $container, $id, $config, $userProviderId) {
$provider = 'security.authentication.provider.ldap_bind.'.$id;
$definition = $container
//->setDefinition($provider, new ChildDefinition('security.authentication.provider.ldap_bind'))
->setDefinition($provider, new ChildDefinition(CustomLdapBindAuthenticationProvider::class))
->replaceArgument(0, new Reference($userProviderId))
->replaceArgument(1, new Reference('security.user_checker.'.$id))
->replaceArgument(2, $id)
->replaceArgument(3, new Reference($config['service']))
->replaceArgument(4, $config['dn_string']);
if (!empty($config['query_string'])) {
$definition->addMethodCall('setQueryString', [$config['query_string']]);
}
return $provider;
}
Я включил службу, как указано в руководстве
App\Security\Authentication\Provider\CustomLdapBindAuthenticationProvider:
arguments:
$userProvider: '@Symfony\Component\Security\Core\User\UserProviderInterface'
$ldap: '@Symfony\Component\Ldap\Ldap'
$dnString: '{username}'
, и поэтому попытался (у меня есть точно объект ChainUserProviderпередал первый аргумент)
App\Security\Authentication\Provider\CustomLdapBindAuthenticationProvider:
arguments:
$userProvider: '@Symfony\Component\Security\Core\User\ChainUserProvider'
$ldap: '@Symfony\Component\Ldap\Ldap'
$dnString: '{username}'
И, наконец, я вставил новый метод в ядро (src / Kernel.php), также я взял его из руководства:
public function build(ContainerBuilder $container)
{
$extension = $container->getExtension('security');
$extension->addSecurityListenerFactory(new CustomFormLoginLdapFactory());
}
но что писать в блоке брандмауэров, для меня не очевидно, и в руководстве по обучению нет никаких инструкций. В результате оригинальный form_login_ldap не работает. попытка заменить form_login_ldap чем-то похожим, например custom_form_login_ldap, не удалась, симфония говорит, что в этой части конфигурации может быть только оригинальное имя.
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
anonymous: true
provider: chain_provider
#http_basic: ~
form_login_ldap:
login_path: /login
check_path: /login
csrf_token_generator: security.csrf.token_manager
service: 'Symfony\Component\Ldap\Ldap'
dn_string: 'cn={username},OU=Staff,OU=Users,OU=Company,DC=company,DC=local'
, когда я запускаю эту конфигурацию:
Service "security.authentication.provider.ldap_bind.main": The argument "0" doesn't exist. (1/1) OutOfBoundsException
Service "security.authentication.provider.ldap_bind.main": The argument "0" doesn't exist. in Definition.php line 275 at Definition->replaceArgument(0, object(Reference))in ResolveChildDefinitionsPass.php line 163 at ResolveChildDefinitionsPass->doResolveDefinition(object(ChildDefinition))in ResolveChildDefinitionsPass.php line 62 at ResolveChildDefinitionsPass->resolveDefinition(object(ChildDefinition))in ResolveChildDefinitionsPass.php line 43 at ResolveChildDefinitionsPass->processValue(object(ChildDefinition), true)in AbstractRecursivePass.php line 82
Итак, как связать фабрику с разделом брандмауэра?