Apiplatform keycloak
AccessTokenHandler
Si vous utilisez un AccessTokenHandler
pour gérer l’authentification avec des tokens d’accès (par exemple, des tokens JWT émis par Keycloak), voici comment configurer votre fichier security.yaml
pour intégrer ce composant.
Configuration de security.yaml
Voici un exemple de configuration pour utiliser un AccessTokenHandler
avec Symfony :
security:
enable_authenticator_manager: true # Activer le système d'authentification moderne de Symfony
providers:
# Définir un fournisseur d'utilisateurs
keycloak:
jwt:
issuer: 'https://your-keycloak-server/auth/realms/your-realm' # URL de Keycloak
audience: 'your-client-id' # Client ID configuré dans Keycloak
public_key: 'your-public-key-from-keycloak' # Clé publique pour valider les tokens
firewalls:
main:
pattern: ^/v1 # Préfixe des routes API Platform (ajustez selon votre configuration)
stateless: true # L'authentification est sans état (stateless)
access_token:
token_handler: App\Security\AccessTokenHandler # Votre AccessTokenHandler personnalisé
provider: keycloak # Utiliser le fournisseur d'utilisateurs configuré
access_control:
# Protéger les routes API
- { path: ^/v1, roles: IS_AUTHENTICATED_FULLY }
Explication des sections
providers
:- Ici, vous définissez un fournisseur d’utilisateurs (
keycloak
) qui utilise un token JWT. - Le fournisseur est configuré pour valider les tokens JWT émis par Keycloak en utilisant :
issuer
: L’URL de Keycloak (le realm).audience
: Le client ID configuré dans Keycloak.public_key
: La clé publique pour valider la signature des tokens.
- Ici, vous définissez un fournisseur d’utilisateurs (
firewalls
:- Le firewall
main
est configuré pour protéger les routes commençant par/v1
(ajustez selon votre préfixe API Platform). - L’option
stateless: true
indique que l’authentification est sans état (typique pour les API). - Le
token_handler
pointe vers votre classeAccessTokenHandler
personnalisée. - Le
provider
est défini pour utiliser le fournisseur d’utilisateurskeycloak
.
- Le firewall
access_control
:- Cette section protège les routes commençant par
/v1
et exige que l’utilisateur soit authentifié (IS_AUTHENTICATED_FULLY
).
- Cette section protège les routes commençant par
Implémentation de AccessTokenHandler
Voici un exemple d’implémentation de AccessTokenHandler
pour valider les tokens JWT émis par Keycloak :
namespace App\Security;
use Symfony\Component\Security\Http\AccessToken\AccessTokenHandlerInterface;
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge;
use Jose\Component\Core\JWKSet;
use Jose\Component\Core\Util\JsonConverter;
use Jose\Component\Signature\JWSVerifier;
use Jose\Component\Signature\Serializer\CompactSerializer;
class AccessTokenHandler implements AccessTokenHandlerInterface
{
private JWKSet $jwkSet;
private JWSVerifier $jwsVerifier;
public function __construct(JWKSet $jwkSet, JWSVerifier $jwsVerifier)
{
$this->jwkSet = $jwkSet;
$this->jwsVerifier = $jwsVerifier;
}
public function getUserBadgeFrom(string $accessToken): UserBadge
{
// Désérialiser le token JWT
$serializer = new CompactSerializer();
$jws = $serializer->unserialize($accessToken);
// Valider la signature du token
if (!$this->jwsVerifier->verifyWithKeySet($jws, $this->jwkSet, 0)) {
throw new BadCredentialsException('Invalid token signature.');
}
// Extraire le payload du token
$payload = JsonConverter::decode($jws->getPayload());
// Récupérer l'identifiant de l'utilisateur (sub)
$userId = $payload['sub'];
// Retourner un UserBadge avec l'identifiant de l'utilisateur
return new UserBadge($userId);
}
}
Enregistrement des services
Dans config/services.yaml
, enregistrez votre AccessTokenHandler
et les services nécessaires :
services:
# Enregistrer l'AccessTokenHandler
App\Security\AccessTokenHandler:
arguments:
$jwkSet: '@web_token.key_set.keycloak' # Le JWKSet pour Keycloak
$jwsVerifier: '@jose.jws_verifier' # Le service de vérification JWS
tags: ['security.access_token_handler']
# Configuration de web-token/jwt-bundle
web_token.key_set.keycloak:
class: Jose\Component\Core\JWKSet
factory: ['Jose\Component\Core\JWKSet', 'createFromKeyData']
arguments:
- { url: 'https://your-keycloak-server/auth/realms/your-realm/protocol/openid-connect/certs' }
- true # is_public
jose.jws_verifier:
class: Jose\Component\Signature\JWSVerifier
arguments:
- '@jose.algorithm_manager' # Gestionnaire d'algorithmes
Tester l’authentification
- Obtenir un token JWT :
- Utilisez Keycloak pour obtenir un token JWT valide pour votre client.
- Envoyer une requête à l’API :
Envoyez une requête à votre API avec le token dans l’en-tête
Authorization
:Authorization: Bearer <votre-token-jwt>
- Vérifier la réponse :
- Si le token est valide, l’utilisateur sera authentifié.
- Si le token est invalide, une erreur
401 Unauthorized
sera retournée.
Conclusion
Avec cette configuration, vous pouvez utiliser un AccessTokenHandler
personnalisé pour valider les tokens JWT émis par Keycloak. Le fichier security.yaml
est configuré pour utiliser ce handler, et les tokens sont validés à l’aide de web-token/jwt-bundle. Cette approche est flexible et s’intègre bien avec Symfony et API Platform.
source:DeepSeek