Apiplatform TokenValidator Lexik
Pour utiliser la classe TokenValidator
dans API Platform, vous devez l’intégrer dans le processus de validation des tokens JWT reçus dans les requêtes. Voici comment vous pouvez procéder :
1. Créer un EventListener ou un Decorator
Vous pouvez créer un EventListener pour intercepter les requêtes entrantes et valider le token JWT avant qu’API Platform ne traite la requête.
a. Créer la classe TokenValidator
Voici un exemple de la classe TokenValidator
que vous avez mentionnée :
namespace App\Service;
use Jose\Component\Core\AlgorithmManager;
use Jose\Component\Core\JWK;
use Jose\Component\Signature\Algorithm\RS256;
use Jose\Component\Signature\JWSVerifier;
class TokenValidator
{
private $jwsVerifier;
public function __construct()
{
$algorithmManager = new AlgorithmManager([new RS256()]);
$this->jwsVerifier = new JWSVerifier($algorithmManager);
}
public function validateToken(string $token, JWK $jwk): bool
{
return $this->jwsVerifier->verifyWithKey($token, $jwk, 0);
}
}
b. Créer un EventListener pour valider le token
Créez un EventListener qui écoute les événements de requête et valide le token JWT.
namespace App\EventListener;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpFoundation\JsonResponse;
use App\Service\TokenValidator;
use Jose\Component\Core\JWK;
class TokenValidationListener
{
private $tokenValidator;
public function __construct(TokenValidator $tokenValidator)
{
$this->tokenValidator = $tokenValidator;
}
public function onKernelRequest(RequestEvent $event): void
{
$request = $event->getRequest();
// Récupérer le token JWT de l'en-tête Authorization
$authHeader = $request->headers->get('Authorization');
if (!$authHeader || !preg_match('/Bearer\s(\S+)/', $authHeader, $matches)) {
$event->setResponse(new JsonResponse(['error' => 'Token missing'], 401));
return;
}
$token = $matches[1];
// Charger la clé publique (JWK) depuis Keycloak ou un autre fournisseur
$jwk = JWK::create([
'kty' => 'RSA',
'n' => 'your-public-key-modulus', // Remplacez par la clé publique
'e' => 'AQAB', // Exposant public
]);
// Valider le token
if (!$this->tokenValidator->validateToken($token, $jwk)) {
$event->setResponse(new JsonResponse(['error' => 'Invalid token'], 401));
}
}
}
c. Enregistrer l’EventListener
Enregistrez l’EventListener dans config/services.yaml
:
services:
App\EventListener\TokenValidationListener:
tags:
- { name: kernel.event_listener, event: kernel.request, method: onKernelRequest }
2. Utiliser un Decorator pour le JWT Authenticator
Si vous utilisez LexikJWTAuthenticationBundle, vous pouvez décorer son authentificateur pour ajouter votre logique de validation.
a. Créer un Decorator
Créez une classe qui décore l’authentificateur JWT de Lexik.
namespace App\Security;
use Lexik\Bundle\JWTAuthenticationBundle\Security\Authenticator\JWTAuthenticator;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use App\Service\TokenValidator;
use Jose\Component\Core\JWK;
class CustomJWTAuthenticator extends JWTAuthenticator
{
private $tokenValidator;
public function __construct(JWTAuthenticator $decorated, TokenValidator $tokenValidator)
{
parent::__construct(
$decorated->getJWTokenManager(),
$decorated->getEventDispatcher(),
$decorated->getTokenExtractor()
);
$this->tokenValidator = $tokenValidator;
}
public function supports(Request $request): ?bool
{
return parent::supports($request);
}
public function getCredentials(Request $request)
{
$credentials = parent::getCredentials($request);
// Valider le token avec TokenValidator
$jwk = JWK::create([
'kty' => 'RSA',
'n' => 'your-public-key-modulus', // Remplacez par la clé publique
'e' => 'AQAB', // Exposant public
]);
if (!$this->tokenValidator->validateToken($credentials['token'], $jwk)) {
throw new AuthenticationException('Invalid token');
}
return $credentials;
}
}
b. Enregistrer le Decorator
Enregistrez le Decorator dans config/services.yaml
:
services:
App\Security\CustomJWTAuthenticator:
decorates: lexik_jwt_authentication.security.jwt_authenticator
arguments:
$decorated: '@.inner'
$tokenValidator: '@App\Service\TokenValidator'
3. Configurer API Platform pour utiliser l’authentification JWT
Dans config/packages/security.yaml
, assurez-vous que le pare-feu est configuré pour utiliser JWT :
security:
enable_authenticator_manager: true
providers:
jwt_provider:
lexik_jwt: ~
firewalls:
api:
pattern: ^/api
stateless: true
jwt: ~
access_control:
- { path: ^/api/login, roles: PUBLIC_ACCESS }
- { path: ^/api, roles: ROLE_USER }
4. Tester la validation du token
- Envoyez une requête à votre API avec un token JWT valide dans l’en-tête
Authorization
. - Si le token est invalide, vous devriez recevoir une réponse
401 Unauthorized
.
Exemple de requête avec curl
:
curl -X GET http://localhost:8000/api/your-endpoint \
-H "Authorization: Bearer your.jwt.token"
5. Documentation supplémentaire
Voir Apiplatform Keycloak Lexik
source:DeepSeek