Symfony2 FOS,未登录时重定向

时间:2014-06-14 14:57:53

标签: symfony fosuserbundle

当没有人没有登录时,我想将用户重定向到登录页面。我写了lister,但是我一直遇到ERR_TOO_MANY_REDIRECTS错误。 也许是实现全局的另一种方法,并重定向用户。检查用户是否已登录每个控制器不是解决方案。

监听\ AccessListener.php

namespace Main\UserBundle\Listener;

use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\Security\Core\SecurityContext;

class AccessListener{

    private $security;
    private $router;

    public function __construct($security, $router){
        $this->security = $security;
        $this->router = $router;
    }

    public function onKernelRequest(GetResponseEvent $event){
        if ($event->isMasterRequest()) {
            if( $this->security->isGranted('IS_AUTHENTICATED_REMEMBERED') ){
                $url = $this->router->generate('fos_user_security_login');
                $event->setResponse(new RedirectResponse($url));
            }
        }
    }
}

security.yml

security:
    access_denied_url: /login
    encoders:
        FOS\UserBundle\Model\UserInterface: sha512

    role_hierarchy:
        ROLE_ADMIN:       ROLE_USER
        ROLE_SUPER_ADMIN: ROLE_ADMIN

    providers:
        fos_userbundle:
            id: fos_user.user_provider.username

    firewalls:
        main:
            pattern: ^/
            form_login:
                provider: fos_userbundle
                csrf_provider: form.csrf_provider
                always_use_default_target_path: false
                default_target_path:            /
            logout:       true
            anonymous:    true

    access_control:
        - { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/register, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/admin/, role: ROLE_ADMIN }

如何更正?

2 个答案:

答案 0 :(得分:4)

您的侦听器正在检查用户是否已登录,如果不是,则会将其转发到登录页面。此时,侦听器会检查用户是否已登录......依此类推......等等。

要停止此重定向循环,您可以检查当前请求的路由是否是您要转发的路由,如此...

public function onKernelRequest(GetResponseEvent $event){
    if ($event->isMasterRequest()) {
        $loginRoute = 'fos_user_security_login';

        $request = $event->getRequest();

        // Return if current route and login route match
        if ($request->get('_route') === $loginRoute) {
            return;
        }

        if( $this->security->isGranted('IS_AUTHENTICATED_REMEMBERED') ){
            $url = $this->router->generate($loginRoute);
            $event->setResponse(new RedirectResponse($url));
        }
    }
}

但是,更好的方法是将根添加到需要登录用户的访问控制部分。这样可以更好地控制可访问和不可访问的路径。

access_control:
    ... current stuff ...
    - { path: ^/, role: ROLE_USER }

答案 1 :(得分:0)

您需要检查当前安全上下文是否成立(或者在您的情况下,如果保持)完全经过身份验证的用户会话,如下所示:

if( false == $this->security->isGranted('IS_FULLY_AUTHENTICATED') ){