Symfony2: проверка подлинности пользователя на основе пути

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

вот мой security.yml:

access_control: - { path: ^/signup/, roles: IS_AUTHENTICATED_ANONYMOUSLY && !IS_AUTHENTICATED_FULLY} - { path: ^/register/, roles: IS_AUTHENTICATED_ANONYMOUSLY && !IS_AUTHENTICATED_FULLY} - { path: ^/recover/, roles: IS_AUTHENTICATED_ANONYMOUSLY && !IS_AUTHENTICATED_FULLY} 

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

  public function onKernelResponse(FilterResponseEvent $event) { $request = $event->getRequest(); $path = $request->getPathInfo(); if($this->container->get('security.context')->getToken() != null) { // To check if user is authenticated or anonymous if( ($this->container->get('security.context')->getToken() instanceof UsernamePasswordToken) && ($this->container->get('security.context')->isGranted('IS_AUTHENTICATED_FULLY') == true) ) { // HOW TO CHECK PATH ? // set response to redirect to home page } } } 

Служба security.access_map

Конфигурация security.access_control обрабатывается …

 SecurityBundle\DependencyInjection\SecurityExtension 

… который создает RequestMatchers для маршрутов (путь, хосты, ip, …), а затем вызывает метод add() службы с помощью соединителя, разрешенных ролей и канала (т. е. https).

Служба обычно используется, например, AccessListener .

Вы можете использовать службу security.access_map для доступа к параметрам security.access_control в своем приложении.

Класс, используемый для службы security.access_map, определяется параметром security.access_map.class и по умолчанию используется

Symfony\Component\Security\Http\AccessMap (реализует AccessMapInterface )

Вы можете использовать параметр security.access_map.class для переопределения службы с помощью специального класса (должен реализовывать AccessMapInterface ):

 # ie app/config/config.yml parameters: security.access_map.class: My\Custom\AccessMap 

Как получить доступ к сервису

Служба security.access_map является частной службой, как вы можете видеть по ее определению здесь .

Это означает, что вы не можете запросить его прямо из контейнера:

$this->container->get('security.access_map')

Вам нужно будет ввести его в другую службу (например, службу прослушивателя), чтобы получить доступ к ней.


Пример слушателя

 services: my_listener: class: My\Bundle\MyListenerBundle\EventListener\ForbiddenRouteListener arguments: [ @security.access_map ] tags: - { name: kernel.event_listener, event: kernel.request, method: onKernelRequest } 

Затем вы можете вызвать метод getPatterns() чтобы получить RequestMatchers, разрешенные роли и необходимый канал оттуда.

 namespace My\Bundle\MyListenerBundle\EventListener; use Symfony\Component\Security\Http\AccessMapInterface; use Symfony\Component\HttpKernel\Event\GetResponseEvent; class ForbiddenRouteListener { protected $accessMap; public function __construct(AccessMapInterface $access_map) { $this->accessMap = $access_map; } public function onKernelRequest(GetResponseEvent $event) { $request = $event->getRequest(); $patterns = $this->accessMap->getPatterns($request); // ... 

Может быть, это поможет кому-то. Я просто поймаю имя маршрута и проверю, находятся ли они в массиве. Если да, просто перенаправите. Это прослушиватель событий.

services.yml

 project.loggedin_listener: class: Project\FrontBundle\EventListener\LoggedInListener arguments: [ "@router", "@service_container" ] tags: - { name: kernel.event_listener, event: kernel.request, method: onKernelRequest } 

слушатель:

 namespace Project\FrontBundle\EventListener; use Symfony\Component\HttpKernel\Event\GetResponseEvent; use Symfony\Component\HttpFoundation\RedirectResponse; class LoggedInListener { private $router; private $container; public function __construct($router, $container) { $this->router = $router; $this->container = $container; } public function onKernelRequest(GetResponseEvent $event) { $container = $this->container; $accountRouteName = "_homepage"; if( $container->get('security.context')->isGranted('IS_AUTHENTICATED_FULLY') ){ $routeName = $container->get('request')->get('_route'); $routes = array("admin_login","fos_user_security_login","fos_user_registration_register","fos_user_resetting_request"); if(in_array($routeName, $routes)){ $url = $this->router->generate($accountRouteName); $event->setResponse(new RedirectResponse($url)); } } } } 

Вы можете использовать не только параметры security.yml, но и через контроллер, например:

 if($securityContext->isGranted('IS_AUTHENTICATED_REMEMBERED')) { return $this->redirect($this->generateUrl('homepage')); }