Symfony 3 аутентификация на страницах под брандмауэром

Проблема, с которой я сталкиваюсь, заключается в том, что я пытаюсь автоматически авторизовать пользователей в разделе профиля моего веб-сайта, но, поскольку он защищен брандмауэром Symfony, пользователи перенаправляются на страницу входа в систему до того, как включится система автологина.

Поэтому мне было интересно, есть ли событие, которое запускается, когда пользователь пытается получить доступ к странице под брандмауэром, которую я мог бы прослушать, или, в конце концов, другой механизм, который я мог бы задействовать для решения этого сценария.

На данный момент исправление, к которому я стремился, заключалось в создании настраиваемого контроллера перенаправления, в который я отправляю своих пользователей с помощью хеша autologin и параметра пути, содержащего конечное местоположение для отправки пользователя, поэтому после аутентификации я перенаправляю их в конечный пункт назначения. ,

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

Спасибо.

D.

0

Решение

По сути, у вас есть три варианта:

1. Создайте пользовательский провайдер аутентификации

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

Вы можете следовать этому руководству в документации: http://symfony.com/doc/current/security/custom_authentication_provider.html
или же http://sirprize.me/scribble/under-the-hood-of-symfony-security/

Дело в том, чтобы создайте свой собственный слушатель брандмауэра, который решает, следует ли аутентифицировать пользователя. Межсетевой экран может иметь несколько слушателей.

2. Слушайте каждый запрос

Кроме того, вы можете слушать kernel.request событие, возможно, вручную проверяя, находитесь ли вы на безопасном пути, и если да, аутентифицировать пользователя вручную вспомогательным методом. Пример:

namespace AppBundle\Subscriber;

use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
use Symfony\Component\Security\Http\SecurityEvents;

class RequestSubscriber implements EventSubscriberInterface
{

private $tokenStorage;

private $eventDispatcher;

public function __construct(TokenStorageInterface $tokenStorage, EventDispatcherInterface $eventDispatcher)
{
$this->tokenStorage = $tokenStorage;
$this->eventDispatcher = $eventDispatcher;
}

public static function getSubscribedEvents()
{
return [ KernelEvents::REQUEST => 'onRequest' ];
}

public function onRequest(GetResponseEvent $event)
{
// only master requests and not authenticated users
if (!$event->isMasterRequest() || $this->isUserLoggedIn()) {
return;
}

// add your own logic for creating or loading a User object
// and filtering secured routes
/* ... */

// wohoo, user is going to be logged in manually!
$this->authenticate($user, $event->getRequest(), 'secured_area');
}

protected function authenticate(UserInterface $user, Request $request, String $provider) : Bool
{
// password doesn't matter in this case
$token = new UsernamePasswordToken($user, null, $provider, $user->getRoles());

// actual authenticating
$this->tokenStorage->setToken($token);

// dispatch the authentication event, so event listeners can do stuff
$loggedUser = $token->getUser();
if ($loggedUser instanceof UserInterface && $loggedUser->isAccountNonLocked() &&
$loggedUser->isEnabled()) {

$this->eventDispatcher
->dispatch(
SecurityEvents::INTERACTIVE_LOGIN,
new InteractiveLoginEvent($request, $token)
);

return true;

}

return false;
}

protected function isUserLoggedIn()
{
$token = $this->tokenStorage->getToken();

if (!$token) {
return false;
}

return ($token->getUser() instanceof UserInterface);
}
}

И не забывай добавить его в приложение / Config / services.yml:

app.request_subscriber:
class: AppBundle\Subscriber\RequestSubscriber
tags:
- { name: kernel.event_subscriber }
arguments: ['@security.token_storage', '@event_dispatcher']

3. Отключить авторизацию

(Вероятно, не решение для вас, так как вы хотите аутентифицировать, а не авторизовать пользователей, но я все еще упоминаю об этом для других.)

В приложение / Config / security.yml, изменить настройки контроля доступа чтобы каждый мог получить доступ к охраняемой территории:

# ...
access_control:
- { path: ^/secured-area$, role: IS_AUTHENTICATED_ANONYMOUSLY }
0

Другие решения

Других решений пока нет …