Symfony2:根据路径检查用户身份验证

时间:2013-11-25 12:34:11

标签: php symfony authentication

在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
      }
    }
  }

3 个答案:

答案 0 :(得分:10)

security.access_map服务

security.access_control 的配置由...

处理
SecurityBundle\DependencyInjection\SecurityExtension

...为路由(路径,主机,IP,...)创建RequestMatcher,然后使用匹配器,允许的角色和通道(即https)调用服务的add()方法。 / p>

该服务通常由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 ):

# i.e. app/config/config.yml

parameters:
    security.access_map.class: My\Custom\AccessMap

如何访问服务

security.access_map服务是私人服务,您可以通过它的定义 here 看到。

这意味着您无法直接从容器中请求它:

$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);

        // ...

答案 1 :(得分:1)

也许这会对某人有所帮助。我只是捕获路由名称并检查它们是否在数组中。如果是,只需重定向。这是事件监听器。

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

        }

    }
}

答案 2 :(得分:0)

您不仅可以在security.yml选项内部,还可以通过控制器,如下所示:

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