в 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')); }