Symfony 4. Авторизация через LDAP. Как настроить AuthenticationProvider? - PullRequest
1 голос
/ 07 октября 2019

Во-первых, извините за мой английский и английский 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

Итак, как связать фабрику с разделом брандмауэра?

1 Ответ

0 голосов
/ 12 октября 2019

используя телеграмму и пользователя artem, проблема была решена. Итак, во-первых, как подключить фабрику к разделу брандмауэра: все было довольно очевидно и быстро обнаружено, невнимательность породила этот вопрос. Может быть кто-то может выполнить поиск, чтобы вопрос остался без ответа

фабричный метод

public function getKey()
{
    return 'form-login-ldap';
}

устанавливает ключ для раздела в брандмауэре: form_login_ldap Только черты превращаются в подчеркивания.

Ну и самое главное, как сделать так, чтобы подключался CustomLdapBindAuthenticationProvider. Оригинальная фабрика, где я взял код для точной копии FormLoginLdapFactory, использует числа в качестве ключей. И это работает для нее, по-видимому, потому, что в глубине конфигов поставщика симфонии описание службы LdapBindAuthenticationProvider использует эти самые цифры для указания аргументов:

->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'])

Когда я сделал для подключения мой CustomLdapBindAuthenticationProvider,Я указал в конфигурации служб:

App\Security\Authentication\Provider\CustomLdapBindAuthenticationProvider:
    arguments:
        $userProvider: '@Symfony\Component\Security\Core\User\UserProviderInterface'
        $userChecker: '@Symfony\Component\Security\Core\User\UserCheckerInterface'
        $providerKey: ''
        $ldap: '@Symfony\Component\Ldap\Ldap'
        $dnString: '{username}'
        $userRepository: '@App\Repository\UserRepository'

и поэтому должен также писать на фабрике:

->setDefinition($provider, new ChildDefinition(CustomLdapBindAuthenticationProvider::class))
->replaceArgument('$userProvider', new Reference($userProviderId))
->replaceArgument('$userChecker', new Reference('security.user_checker.'.$id))
->replaceArgument('$providerKey', $id)
->replaceArgument('$ldap', new Reference($config['service']))
->replaceArgument('$dnString', $config['dn_string'])

И это сработало.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...