O
O
Oleg Krasavin2015-08-19 16:23:17
symfony
Oleg Krasavin, 2015-08-19 16:23:17

How to hide route from logged in users in Symfony2?

We have a standard install of SF 2.7 + FOSUB 2.0 branches.
You need to set up a redirect to homepage( / ) with /auth/ if the user is logged in.
Firewall is almost default:

firewalls:
        dev:
            pattern:  ^/(_(profiler|wdt)|css|images|js)/
            security: false

        # secures part of the application
        main:
            pattern: ^/
            form_login:
                login_path: /auth/login
                check_path: /auth/login_check

                provider: fos_userbundle
                default_target_path:  /
                csrf_provider: security.csrf.token_manager

            logout:
                path:   /auth/logout
                target: /
                invalidate_session: true
            anonymous:    true

    access_control:
        - { path: ^/admin/, role: ROLE_ADMIN }
        - { path: ^/, role: ROLE_USER }

So far, only the option with an additional rule in access_control comes to mind:
- { path: ^/auth/,  allow_if: "!is_fully_authenticated()" }

And by creating a listener that would catch AccessDeniedException, check the current route and redirect to the right place. But IMHO this is a fierce overhead projector for such a basic task.
UPD: I decided to leave the EventListener:
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Router;

class AccessDeniedListener {
    
    protected $_session;
    protected $_router;
    protected $_request;

    public function __construct(Session $session, Router $router, Request $request){
        $this->_session = $session;
        $this->_router  = $router;
        $this->_request = $request;
    }

    public function onAccessDeniedException(GetResponseForExceptionEvent $event) {

        if ($event->getException() instanceof AccessDeniedHttpException){
            $this->_session->getFlashBag()->add('error', 'Access Denied. You do not have permission to access this page.');

            if ($this->_request->headers->get('referer')){
                $route = $this->_request->headers->get('referer');
            } else {
                $route = $this->_router->generate('starlight_home');
            }

            $event->setResponse(new RedirectResponse($route));
        }
    }
}

Services.yml:
services:
    starlight.access_denied_listener:
        class: okwinza\AppBundle\EventListener\AccessDeniedListener
        arguments: ["@session", "@router", "@=service('request_stack').getCurrentRequest()"]
        tags:
            - { name: kernel.event_listener, event: kernel.exception, method: onAccessDeniedException }

Answer the question

In order to leave comments, you need to log in

2 answer(s)
N
nonlux, 2015-08-19
@okwinza

Actually, I seem to have done

security.yml
        -
            path: ^/register
            allow_if: "!has_role('ROLE_USER')"

+ customize 403 redirect page

R
romashka_sky, 2015-08-19
@romashka_sky

Why not just override the controller FOSUserBundle:Security:loginwith redirect functionality

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question