I know that this might be silly, but it's quite an annoying behaviour.
The scenario is:
I know that this is related to the firewall configuration. However, shouldn't a user be redirected to another page as the user is already logged in?
Checking this in the loginAction should do the work.
@herodrigues this happend with reset password related actions too
IMO, its more of symfony problem since im not aware of any quick&proper solution for it.
As a workaround you can restrict all these routes in your firewall config, create a 403 listener and handle redirect there(while setting flashmessage for example).
Definitely a bug we need to somehow handle. :) @okwinza solution seems like best what we have right now.
Is it really a bug? I don't think the page should be accessible, but it is harmless and doesn't break anything :)
@michalmarcinkowski I think it can be confusing for the user. I'd say it is not critical bug. :P
You can either create a 403 by adding:
- { path: ^/admin/login, role: IS_AUTHENTICATED_ANONYMOUSLY && !IS_AUTHENTICADED_FULLY }
But the best solution seems, to have a listener and redirect your to the dashboard. I'll create a PR for this right now.
As a clarification a user who is logged in can still access these pages:
I've tried looking through options for 403 handlers (authentication error handlers) but I can't seem to get a configuration that works. The config:
IS_AUTHENTICATED_ANONYMOUSLY && !IS_AUTHENTICADED_FULLY does not appear to work and non-logged in users are prevented access too and directed to the login page. I think this may need to be done within the controllers, which at least for the SecurityController, is a final class so cannot be overwritten.
Figured out a complete solution:
security.yml
#...
firewalls:
#...
shop:
access_denied_handler: sylius.shop.access_denied_handler
#...
access_control:
#...
- { path: "%sylius.security.shop_regex%/login", allow_if: "is_anonymous()" }
- { path: "%sylius.security.shop_regex%/register", allow_if: "is_anonymous()" }
#...
- { path: "%sylius.security.shop_regex%/forgotten-password", allow_if: "is_anonymous()" }
services.yml
services:
#...
sylius.shop.access_denied_handler:
class: AppBundle\Security\AccessDeniedHandler
arguments:
- '@router'
- '@security.authorization_checker'
- '@session'
- '@translator'
AccessDeniedHandler.php
<?php
namespace AppBundle\Security;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
use Symfony\Component\Security\Http\Authorization\AccessDeniedHandlerInterface;
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
use Symfony\Component\Translation\TranslatorInterface;
class AccessDeniedHandler implements AccessDeniedHandlerInterface {
private $router;
private $authChecker;
private $session;
private $translator;
public function __construct(
RouterInterface $router,
AuthorizationCheckerInterface $authChecker,
SessionInterface $session,
TranslatorInterface $translator
)
{
$this->router = $router;
$this->authChecker = $authChecker;
$this->session = $session;
$this->translator = $translator;
}
public function handle(Request $request, AccessDeniedException $accessDeniedException)
{
if( $this->authChecker->isGranted('IS_AUTHENTICATED_FULLY') )
{
$this->session->getFlashBag()->add('info', $this->getFlashMessage('sylius.customer.already_logged_in'));
return new RedirectResponse($this->router->generate('sylius_shop_account_dashboard'));
}
}
private function getFlashMessage($key)
{
return $this->translator->trans($key, [], 'flashes');
}
}
flashes.yml
sylius:
customer:
already_logged_in: 'You are already logged in'
I think that sorts it out.
Most helpful comment
Figured out a complete solution:
security.yml
services.yml
AccessDeniedHandler.php
flashes.yml
I think that sorts it out.