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 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
| <?php
namespace App\Security;
use Firebase\JWT\JWT;
use Firebase\JWT\Key;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Http\Authenticator\Passport\Passport;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Http\Authenticator\AbstractAuthenticator;
use Lexik\Bundle\JWTAuthenticationBundle\Services\JWTTokenManagerInterface;
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge;
use Lexik\Bundle\JWTAuthenticationBundle\Exception\JWTDecodeFailureException;
use Symfony\Component\Security\Core\Authentication\Token\PreAuthenticatedToken;
use Symfony\Component\Security\Http\Authenticator\Passport\SelfValidatingPassport;
use Lexik\Bundle\JWTAuthenticationBundle\Security\Authentication\Token\PreAuthenticatedJWTUserToken;
class TokenAuthenticator extends AbstractAuthenticator
{
private $logger;
private $userProvider;
private $publicKeyPath;
private $jwtTokenManager;
public function __construct(
LoggerInterface $logger,
UserProviderInterface $userProvider,
string $publicKeyPath,
JWTTokenManagerInterface $jwtTokenManager
) {
$this->logger = $logger;
$this->userProvider = $userProvider;
$this->publicKeyPath = $publicKeyPath;
$this->jwtTokenManager = $jwtTokenManager;
}
public function supports(Request $request): ?bool
{
// Log all headers for debugging
$headers = $request->headers->all();
$this->logger->info('Request headers', $headers);
$authHeader = $request->headers->get('Authorization');
if ($authHeader === null || strpos($authHeader, 'Bearer ') !== 0) {
$this->logger->info('Authorization header missing or incorrect');
return false;
}
$this->logger->info('Authorization header found and correct');
return true;
}
public function authenticate(Request $request): Passport
{
$authHeader = $request->headers->get('Authorization');
if (!$authHeader || !str_starts_with($authHeader, 'Bearer ')) {
throw new AuthenticationException('No Bearer token found');
}
$jwt = str_replace('Bearer ', '', $authHeader);
$this->logger->info('JWT Token: ' . $jwt);
try {
// Utiliser JWTTokenManagerInterface pour décoder le token
$payload = $this->jwtTokenManager->decode($jwt);
} catch (JWTDecodeFailureException $e) {
throw new AuthenticationException('Invalid JWT token');
}
// Vérification de l'expiration
if (isset($payload['exp']) && $payload['exp'] < time()) {
throw new AuthenticationException('Token has expired');
}
if (!is_array($payload) || !isset($payload['username'])) {
throw new AuthenticationException('Invalid JWT payload');
}
$userIdentifier = $payload['username'];
return new SelfValidatingPassport(
new UserBadge($userIdentifier, function ($userIdentifier) {
$user = $this->userProvider->loadUserByIdentifier($userIdentifier);
// Logging des rôles de l'utilisateur
$roles = implode(', ', $user->getRoles());
$this->logger->info('User roles: ' . $roles);
return $user;
})
);
}
public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $firewallName): ?Response
{
$this->logger->info('Authentication successful');
return null;
}
public function onAuthenticationFailure(Request $request, AuthenticationException $exception): ?Response
{
$this->logger->warning('Authentication failed: ' . $exception->getMessage());
return new JsonResponse(['message' => $exception->getMessage()], Response::HTTP_UNAUTHORIZED);
}
} |
Partager