Reputation: 3416
I'd like to redirect user to login page when nobody is not logged in. I wrote lister to that, but all the time I'm getting ERR_TOO_MANY_REDIRECTS
error.
Maybe is another method to achieve it globaly, and redirect user. Checking if user is logged in every controller is not a solution.
Listener\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 }
How do I correct it?
Upvotes: 1
Views: 3626
Reputation: 17759
Your listener is checking whether a user is logged in and then, if they are not, they are being forwarded to the login page. At which point the listener checks whether the user is logged in... and so on.. and so on.
To stop this redirect loop you could check whether the current route being requested is the route that you are forwarding to, like so...
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));
}
}
}
However, a better way of doing this would be to add the root to the access control section needing a logged in user. This would allow you to have a better control over accessible and inaccessible paths.
access_control:
... current stuff ...
- { path: ^/, role: ROLE_USER }
Upvotes: 4
Reputation: 1678
You need to check whether the current security context holds (or in your case if it does not hold) a fully authenticated user session as follows:
if( false == $this->security->isGranted('IS_FULLY_AUTHENTICATED') ){
Upvotes: 0