pdoServices = $pdoServices; $this->session = $session; $this->client = $client; $this->router = $router; } /** * @Route("/oauth/login", name="app_login") */ public function loginOidc(Request $request) { $challenge = $request->query->get('login_challenge'); // S'il n'y a pas de challenge, on déclenche une bad request if (!$challenge) { throw new BadRequestException('pas de challenge'); } // On vérifie que la requête d'identification provient bien de hydra $response = $this->client->request('GET', $this->getParameter('url_login_challenge').$challenge, [ 'headers' => [ 'Content-Type: application/json', ], ]); if (200 !== $response->getStatusCode()) { $this->session->clear(); throw new BadRequestException('pa de code 200'); } // si le challenge est validé par hydra, on le stocke en session pour l'utiliser par la suite et on redirige vers une route interne protégée qui va déclencher l'identification FranceConnect $this->session->set('challenge', $challenge); return $this->redirectToRoute('oauth_login'); } /** * @Route("/oauth/connect", name="oauth_login") */ public function oauth(Request $request) { if ($request->headers->get('referer') !== $this->router->generate('oauth_login', [], 0) && !in_array($request->headers->get('referer'), $this->getParameter('urlIssuer'))) { throw new BadRequestException('Vous devez passer par le issuer pour vous connecter'); } $user = new User(); $loginForm = $this->createForm(UserType::class, $user); $loginForm->handleRequest($request); if ($loginForm->isSubmitted() && $loginForm->isValid()) { $email = $loginForm->get('email')->getData(); try { // requête préparée $datas = $this->pdoServices->fetchDatas($email); if (!$datas) { // Si le hash du password n'est pas trouvé, c'est que l'email n'existe pas, on retourne la page de login avec une erreur return $this->render('login.html.twig', [ 'form' => $loginForm->createView(), 'error_mail' => 'mail non trouvé', ]); } $hashPassword = $datas[$this->getParameter('passwordColumnName')]; $password = $loginForm->get('password')->getData(); if ($this->pdoServices->verifyPassword($password, $hashPassword)) { // On défait la mot de passe qui ne servira plus unset($datas[$this->getParameter('passwordColumnName')]); $this->session->set('datas', $datas); $response = $this->client->request('PUT', $this->getParameter('url_login_challenge_accept').$this->session->get('challenge'), [ 'json' => [ 'subject' => $email, 'acr' => 'string', ], ]); // On initie l'acceptation du login challenge émis par hydra et on récupère l'url de redirection $redirect_to = $response->toArray()['redirect_to']; return $this->redirect($redirect_to, 301); } else { return $this->render('login.html.twig', [ 'form' => $loginForm->createView(), 'error_password' => 'Le mot de passe est incorrect', ]); } } catch (\Exception $e) { dd($e); } } return $this->render('login.html.twig', [ 'form' => $loginForm->createView(), ]); } /** * @Route("/oauth/consent", name="consent") */ public function consent(Request $request) { $challenge = $request->query->get('consent_challenge'); if (!$challenge) { throw new BadRequestException("Le challenge n'est pas disponible"); } // Vérification du consent_challenge avec hydra $response = $this->client->request('GET', $this->getParameter('url_consent_challenge').$challenge, [ 'headers' => [ 'Content-Type: application/json', ], ]); if (200 !== $response->getStatusCode()) { $this->session->clear(); throw new BadRequestException("Le challenge n'est pas authorisé"); } $response = $this->client->request('PUT', $this->getParameter('url_consent_challenge_accept').$challenge, [ 'headers' => [ 'Content-Type: application/json', ], 'json' => [ 'grant_scope' => ['openid', 'offline_access'], 'session' => [ 'id_token' => [ 'user' => $this->session->get('datas'), ], ], ], ]); $redirect_to = $response->toArray()['redirect_to']; return $this->redirect($redirect_to, 301); } /** * @Route("/oauth/logout", name="app_logout") */ public function logout() { $this->session->clear(); return $this->redirect($this->getParameter('urlLogoutSuccess')); } }