environnement complet autonome, révision complete de la méthode, ajout de configuration
This commit is contained in:
@ -3,171 +3,55 @@
|
||||
namespace App\Controller;
|
||||
|
||||
use App\Entity\User;
|
||||
use App\Form\UserType;
|
||||
use App\Services\PdoServices;
|
||||
use App\Hydra\Client;
|
||||
use App\Hydra\HydraService;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\HttpFoundation\Exception\BadRequestException;
|
||||
use Symfony\Component\HttpFoundation\RedirectResponse;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Session\SessionInterface;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
|
||||
use Symfony\Contracts\HttpClient\HttpClientInterface;
|
||||
|
||||
class MainController extends AbstractController
|
||||
{
|
||||
/**
|
||||
* @var Session
|
||||
*/
|
||||
private $session;
|
||||
public HydraService $hydra;
|
||||
public Client $client;
|
||||
public SessionInterface $session;
|
||||
|
||||
/**
|
||||
* @var UrlGeneratorInterface
|
||||
*/
|
||||
private $router;
|
||||
|
||||
/**
|
||||
* @var HttpClientInterface
|
||||
*/
|
||||
public $client;
|
||||
private $pdoServices;
|
||||
|
||||
public function __construct(PdoServices $pdoServices, HttpClientInterface $client, SessionInterface $session, UrlGeneratorInterface $router)
|
||||
public function __construct(SessionInterface $session, HydraService $hydra, Client $client)
|
||||
{
|
||||
$this->pdoServices = $pdoServices;
|
||||
$this->session = $session;
|
||||
$this->client = $client;
|
||||
$this->router = $router;
|
||||
$this->hydra = $hydra;
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route("/oauth/login", name="app_login")
|
||||
* @Route("/", name="app_home")
|
||||
*/
|
||||
public function loginOidc(Request $request)
|
||||
public function home(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');
|
||||
return $this->hydra->handleLoginRequest($request);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route("/oauth/connect", name="oauth_login")
|
||||
* @Route("/connect/login-accept", name="app_login_accept")
|
||||
*/
|
||||
public function oauth(Request $request)
|
||||
public function loginAccept(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');
|
||||
}
|
||||
/** @var User */
|
||||
$user = $this->getUser();
|
||||
$loginAcceptRes = $this->client->acceptLoginRequest($this->session->get('challenge'), [
|
||||
'subject' => $user->getLogin(),
|
||||
'remember' => true,
|
||||
])->toArray();
|
||||
|
||||
$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(),
|
||||
]);
|
||||
return new RedirectResponse($loginAcceptRes['redirect_to']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route("/oauth/consent", name="consent")
|
||||
* @Route("/connect/consent", name="app_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'));
|
||||
return $this->hydra->handleConsentRequest($request);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user