Пользовательский поставщик аутентификации Symfony с несколькими брандмауэрами - PullRequest
0 голосов
/ 02 июля 2018

Я создан как пользовательский поставщик аутентификации, как указано в официальной документации Symfony https://symfony.com/doc/3.4/security/custom_authentication_provider.html

Затем я использовал один и тот же пользовательский поставщик аутентификации для разных брандмауэров, у которых был отдельный пользовательский провайдер с другим объектом.

#app/config/security.yml

#...
providers:
    abcuser:
        id: App\Bundle\AbcBundle\Security\UserProvider
    xyzuser:
        id: App\Bundle\XyzBundle\Security\UserProvider
    pqruser:
        id: App\Bundle\PqrBundle\Security\UserProvider

firewalls:
    api_token:
        pattern: ^/((api/v1/abc/auth/token)|(api/v1/xyz/auth/token)|(api/v1/pqr/auth/token))$
        stateless: true
        anonymous: true
    api_abc:
        pattern: ^/api/v1/abc
        stateless: true
        provider: abcuser
        custom_auth: true
    api_xyz:
        pattern: ^/api/v1/xyz
        stateless: true
        provider: xyzuser
        custom_auth: true
    api_pqr:
        pattern: ^/api/v1/pqr
        stateless: true
        provider: pqruser
        custom_auth: true

   #...

Теперь, когда я генерирую токен доступа с api/v1/pqr/auth/token и запрашиваю api с api/v1/pqr/details, чтобы получить сведения о пользователе для pqr.

Скажем, у меня есть пользователь с именем пользователя apple на pqr и такое же имя пользователя существует на abc , затем он возвращает сведения о пользователе apple из abc . Но похоже, что firewall pqr активируется, но пользовательский провайдер используется сверху вниз.

Глядя на AuthenticationProviderManager в Symfony, кажется, что он перебирает список поставщиков. (строка № 15)

<?php
// ...
namespace Symfony\Component\Security\Core\Authentication;

class AuthenticationProviderManager implements AuthenticationManagerInterface
{
  // ...

public function authenticate(TokenInterface $token)
{
    $lastException = null;
    $result = null;

    // this might be issue
    foreach ($this->providers as $provider) {
        if (!$provider instanceof AuthenticationProviderInterface) {
            throw new \InvalidArgumentException(sprintf('Provider "%s" must implement the AuthenticationProviderInterface.', get_class($provider)));
        }

        if (!$provider->supports($token)) {
            continue;
        }

        try {
            $result = $provider->authenticate($token);

            if (null !== $result) {
                break;
            }
        } catch (AccountStatusException $e) {
            $lastException = $e;

            break;
        } catch (AuthenticationException $e) {
            $lastException = $e;
        }
    }

    if (null !== $result) {
        if (true === $this->eraseCredentials) {
            $result->eraseCredentials();
        }

        if (null !== $this->eventDispatcher) {
            $this->eventDispatcher->dispatch(AuthenticationEvents::AUTHENTICATION_SUCCESS, new AuthenticationEvent($result));
        }

        return $result;
    }

    if (null === $lastException) {
        $lastException = new ProviderNotFoundException(sprintf('No Authentication Provider found for token of class "%s".', get_class($token)));
    }

    if (null !== $this->eventDispatcher) {
        $this->eventDispatcher->dispatch(AuthenticationEvents::AUTHENTICATION_FAILURE, new AuthenticationFailureEvent($token, $lastException));
    }

    $lastException->setToken($token);

    throw $lastException;
}
//...
}

Подскажите, пожалуйста, куда я скучаю?

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