La configuration des firewall de Symfony permet de spécifier url de redirection en cas d'authentification réussit grâce à l'option default_target_path
des form_login
. Hélas vous ne pouvez pas personnaliser cette url en fonction de l'utilisateur, ce qui peux s'avérer utile si par exemple vous avez différent roles et que vous souhaitez rediriger votre utilisateur sur une page avec des accès restreint.
Authentication success handler
Pour cela, vous devez créer un authentication success handler personnaliser. Vous pouvez soit en créer un de tout pièce en prenant soins d'implémenter l'interface AuthenticationSuccessHandlerInterface
, soit hériter du DefaultAuthenticationSuccessHandler
et redéfinir la méthode determineTargetUrl
.
<?php
namespace Acme\Bundle\AppBundle\Security;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
use Symfony\Component\Security\Http\Authentication\DefaultAuthenticationSuccessHandler;
use Symfony\Component\Security\Http\HttpUtils;
class CustomAuthenticationSuccessHandler extends DefaultAuthenticationSuccessHandler
{
private $authorizationChecker;
public function __construct(HttpUtils $httpUtils, array $options = [], AuthorizationCheckerInterface $authorizationChecker = null)
{
$this->authorizationChecker = $authorizationChecker;
parent::__construct($httpUtils, $options);
}
protected function determineTargetUrl(Request $request)
{
// Redirect to the wanted page
if (null !== $this->providerKey && $targetUrl = $request->getSession()->get('_security.'.$this->providerKey.'.target_path')) {
$request->getSession()->remove('_security.'.$this->providerKey.'.target_path');
return $targetUrl;
}
// My redirection logic
if ($this->authorizationChecker->isGranted('ROLE_FOOBAR') {
return $this->httpUtils->generateUri($request, 'foobar');
}
// Default behavior
return parent::determineTargetUrl($request);
}
}
Ici par exemple, cet handler va rediriger les utilisateurs ayant le role ROLE_FOOBAR
vers la route foobar
. Pour les autres, le comportement par défaut s'appliquera.
Configuration
Déclarer votre service :
services:
acme.security.custom_authentication_success_handler:
class: Acme\Bundle\AppBundle\Security\CustomAuthenticationSuccessHandler
arguments:
- @security.http_utils
- []
- @?security.authorization_checker
Puis spécifier au form_login
d'utiliser cet handler :
security:
firewalls:
secured_area:
pattern: ^/
anonymous: ~
form_login:
success_handler: acme.security.custom_authentication_success_handler
Désormais, pour ce firewall, le nouveau handler sera utiliser. Pensez à le configurer sur vos autres firewall si besoin.
Les commentaires