feat(security): Crée AccessDeniedHandler et AuthenticationEntryPoint pour gérer l'accès.

♻️ refactor(security): Remplace `custom_authenticators` par `custom_authenticator`.
⚙️ chore(framework): Active le cache HTTP et configure la session.
This commit is contained in:
Serreau Jovann
2025-11-22 22:58:59 +01:00
parent af21127ce2
commit 5f77fa5b37
4 changed files with 101 additions and 4 deletions

View File

@@ -2,8 +2,14 @@
framework:
secret: '%env(APP_SECRET)%'
session: true
http_cache:
enabled: true
default_ttl: 3600
stale_while_revalidate: 3600
stale_if_error: 3600
session:
cookie_secure: auto
cookie_samesite: lax
#esi: true

View File

@@ -24,8 +24,8 @@ security:
check_path: app_login # L'URL où le formulaire POST sera soumis
enable_csrf: true # Active la protection CSRF
csrf_token_id: authenticate # ID du jeton CSRF (doit correspondre à celui dans votre Twig)
entry_point: App\Security\LoginFormAuthenticator
custom_authenticators:
entry_point: App\Security\AuthenticationEntryPoint
custom_authenticator:
- App\Security\LoginFormAuthenticator

View File

@@ -0,0 +1,35 @@
<?php
namespace App\Security;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
use Symfony\Component\Security\Http\Authorization\AccessDeniedHandlerInterface;
use Twig\Environment;
class AccessDeniedHandler implements AccessDeniedHandlerInterface
{
public function __construct(private readonly UrlGeneratorInterface $urlGenerator, private readonly Environment $twig)
{
}
public function handle(Request $request, AccessDeniedException $accessDeniedException): Response
{
$attributes = $accessDeniedException->getAttributes();
$pathInfo = $request->getPathInfo();
if (str_contains($pathInfo, "/admin")) {
return new RedirectResponse($this->urlGenerator->generate("app_home"));
}
if (in_array('application/json', $request->getAcceptableContentTypes())) {
return new JsonResponse(null, Response::HTTP_FORBIDDEN);
}
return new JsonResponse(null, Response::HTTP_FORBIDDEN);
}
}

View File

@@ -0,0 +1,56 @@
<?php
namespace App\Security;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Security\Core\Authentication\Token\RememberMeToken;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\Exception\InsufficientAuthenticationException;
use Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface;
class AuthenticationEntryPoint implements AuthenticationEntryPointInterface
{
/**
* @var \Symfony\Component\Routing\Generator\UrlGeneratorInterface|mixed
*/
public $urlGenerator;
/**
* @var AccessDeniedHandler|mixed
*/
public $accessDeniedHandler;
public function __construct(
UrlGeneratorInterface $urlGenerator,
AccessDeniedHandler $accessDeniedHandler
) {
$this->urlGenerator = $urlGenerator;
$this->accessDeniedHandler = $accessDeniedHandler;
}
public function start(Request $request, AuthenticationException $authException = null): Response
{
$previous = $authException !== null ? $authException->getPrevious() : null;
// Parque le composant security est un peu bête et ne renvoie pas un AccessDenied pour les utilisateur connecté avec un cookie
// On redirige le traitement de cette situation vers le AccessDeniedHandler
if ($authException instanceof InsufficientAuthenticationException &&
$previous instanceof AccessDeniedException &&
$authException->getToken() instanceof RememberMeToken
) {
return $this->accessDeniedHandler->handle($request, $previous);
}
if (in_array('application/json', $request->getAcceptableContentTypes())) {
return new JsonResponse(
['title' => "Vous n'avez pas les permissions suffisantes pour effectuer cette action"],
Response::HTTP_FORBIDDEN
);
}
return new RedirectResponse($this->urlGenerator->generate('frontend_login'));
}
}