Bonjour, j'aimerai vous évoquer un petit problème qui ne doit être bien méchant mais il me manque un quelque chose que je ne saisit pas.
Ce que j'essaye de mettre en place :
- Mettre un filtre qui n'autorise pas l'accès aux service demandé si l'utilisateur n'est pas connu de la base de donnée (soit, enregistré)
- Ce filtre redirige vers la page d'accueil pour que l'anonyme se loggue/S'inscrive si ce n'est déjà fait
- Après être connu loggué/enregistrer, il est redirigé vers sa page qu'il souhaité.
Ce que j'ai déjà fait :
Mis en place le filtre. (Je travail avec le framework symfony 2; Php 5; Pgsql, annotation)
J'ai suivis cette procédure très intéressante expliqué sur cette page qui est aussi expliqué d'une autre manière que le site de symfony.
L'idée suggéré est de lier un Listener à un controller auquel on va rattaché un service, donc une méthode, qui sera appellé avant chaque action désiré de ce controller. En d'autre termes, à chaque fois que l'on fera appel à un service dans ce controller, une méthode sera exécuté avant (ici, preExecute).
La méthode preExecute que j'ai écrite :
Cela me redirige bien vers ma page d'accueil si l'utilisateur n'est connu à travers l'exception émise qui du coup ne redirige nulle par et qui par défaut est orienté vers ma page de login (action nommé "start") suite a la config effectué dans le fichier security.yml
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13 public function preExecute() { $logger = $this->get('logger'); $logger->info('Slug '.__CLASS__.' preExecute : start'); $user = $this->container->get('security.context')->getToken()->getUser(); // Pour vérifier que l'utilisateur est authentifié (et non un anonyme) if( ! is_object($user) ) { throw new AccessDeniedException('Vous n\'êtes pas authentifié.'); } $logger->info('Slug '.__CLASS__.' preExecute : end'); }
Hors j'ai essayé d'autre manière plutôt de que de faire un "crash" et que ce soit le système de sécurité qui sache faire plutôt que ma fonction. (même si l'auto-délation est intéressante aussi)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 firewalls: main: pattern: ^.* form_login: provider: fos_userbundle login_path: fos_user_security_login check_path: fos_user_security_check csrf_provider: form.csrf_provider default_target_path: start
Je voulais tenter ceci :
Il se passe que si je ne suis authentifié est que j'accéde à une url nommé "B" soumis à l'écoute de ce filtre, la fonction preExecute le détecte et entre dans le catch puis forward vers ma page "login" mais appel après l'url "B". Donc en fait ma fonction ne sert à rien..
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 public function preExecute() { $logger = $this->get('logger'); try { $logger->info('Slug '.__CLASS__.' preExecute : start'); $user = $this->container->get('security.context')->getToken()->getUser(); if( ! is_object($user) ) { throw new AccessDeniedException('Vous n\'êtes pas authentifié.'); } $logger->info('Slug '.__CLASS__.' preExecute : end'); }catch (\Exception $e) { $logger->info('Slug '.__CLASS__.' preExecute : fail _ '.$e); //$uri = $this->generateUrl('start'); //return $this->redirect($uri); $response = $this->forward('PldSlugBundle:Default:index'); return $response; } }
Dans le premier cas, il n'y a pas de catch donc le processus plante et on est redirigé de part la config de sécurité vers la page login.
Dans le deuxième cas l’exception n'est pas bloquante donc le processus se poursuit.
C'est ici que je ne comprend pas, j'aurai pensé que dès lors que j'aurai retourné une "réponse" mon service "B" n'aurait été appelé, hors c'est le cas.
Comment faire pour effectuer cette redirection avec un catch ?
Je précise que si je fait la redirection dans ma condition if (! isObject($user)) cela revient au même.
Puis ensuite j'aimerai bien qu'après s'être loggué le service demandé "B" soit "automatiquement" rappelé (suite à une redirection sans doute).
J'avais pensé à un truc du genre
Mais comment la fonction preExecute peut bien connaitre le service demandé ? donc je ne vois pas bien...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 $response = $this->forward('PldSlugBundle:Default:index',(array($url->url))); return $response;
Puis transité cette url à travers FOsUserBundle n'est peut-être pas aussi simple..
Si vous auriez des idées pour répondre à ces problématiques, je vous en remercie d'avance.
Partager