Aller au contenu

Apiplatform Keycloak Lexik

De Marmits Wiki

Pour intégrer API Platform 4 avec Keycloak 26 en utilisant OpenID Connect (OIDC), vous devez configurer l’authentification JWT et sécuriser vos routes API. Voici un guide détaillé pour configurer l’ensemble :


1. Prérequis

  • API Platform 4 : Déjà installé et configuré.
  • Keycloak 26 : Un fournisseur OIDC configuré avec un client pour votre application.
  • LexikJWTAuthenticationBundle : Pour gérer les JWT dans Symfony.



2. Installation des dépendances

Installez les packages nécessaires via Composer :

composer require web-token/jwt-framework
composer require lexik/jwt-authentication-bundle
composer require league/oauth2-client

3. Configuration de LexikJWTAuthenticationBundle

a. Configurer les clés JWT

Générez les clés privée et publique pour signer les JWT :

mkdir -p config/jwt
openssl genpkey -out config/jwt/private.pem -aes256 -algorithm rsa -pkeyopt rsa_keygen_bits:4096
openssl pkey -in config/jwt/private.pem -out config/jwt/public.pem -pubout

Ajoutez les variables d’environnement dans .env :

###> lexik/jwt-authentication-bundle ###
JWT_SECRET_KEY=%kernel.project_dir%/config/jwt/private.pem
JWT_PUBLIC_KEY=%kernel.project_dir%/config/jwt/public.pem
JWT_PASSPHRASE=your_passphrase
###< lexik/jwt-authentication-bundle ###

b. Configurer lexik_jwt_authentication.yaml

Ajoutez la configuration suivante dans config/packages/lexik_jwt_authentication.yaml :

lexik_jwt_authentication:
    secret_key: '%env(resolve:JWT_SECRET_KEY)%'
    public_key: '%env(resolve:JWT_PUBLIC_KEY)%'
    pass_phrase: '%env(JWT_PASSPHRASE)%'
    token_ttl: 3600 # Durée de validité du token (en secondes)

4. Configuration de Keycloak

a. Configurer Keycloak

  1. Créez un client dans Keycloak.
  2. Notez les informations suivantes :
    • Client ID : Identifiant du client.
    • Client Secret : Clé secrète du client.
    • Issuer URL : URL du fournisseur (par exemple, https://keycloak.example.com/auth/realms/{realm}).
    • Authorization URL : URL d’autorisation.
    • Token URL : URL pour obtenir les tokens.
    • Userinfo URL : URL pour récupérer les informations de l’utilisateur.

b. Configurer Symfony

Ajoutez les informations du fournisseur dans votre fichier .env :

###> OIDC Configuration ###
OIDC_CLIENT_ID=your-client-id
OIDC_CLIENT_SECRET=your-client-secret
OIDC_ISSUER=https://keycloak.example.com/auth/realms/{realm}
OIDC_AUTHORIZATION_URL=https://keycloak.example.com/auth/realms/{realm}/protocol/openid-connect/auth
OIDC_TOKEN_URL=https://keycloak.example.com/auth/realms/{realm}/protocol/openid-connect/token
OIDC_USERINFO_URL=https://keycloak.example.com/auth/realms/{realm}/protocol/openid-connect/userinfo
###< OIDC Configuration ###

5. Configurer le composant Security

Dans config/packages/security.yaml, configurez le pare-feu pour utiliser JWT et OIDC.

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 }

6. Créer un contrôleur d’authentification

Créez un contrôleur pour gérer la connexion via OIDC et la génération des tokens JWT.

namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\Routing\Annotation\Route;
use App\Service\OidcService;

class AuthController extends AbstractController
{
    #[Route('/api/login', name: 'api_login', methods: ['POST'])]
    public function login(OidcService $oidcService): JsonResponse
    {
        $accessToken = $oidcService->getAccessToken($_POST['code']);
        $userInfo = $oidcService->getUserInfo($accessToken);

        // Authentifiez l'utilisateur avec les informations de $userInfo
        // ...

        // Générer un token JWT
        $jwtToken = $this->getToken($userInfo);

        return $this->json([
            'user' => $userInfo['email'],
            'token' => $jwtToken,
        ]);
    }

    private function getToken(array $userInfo): string
    {
        return $this->container->get('lexik_jwt_authentication.encoder')
            ->encode(['username' => $userInfo['email']]);
    }
}

7. Configurer API Platform

a. Sécuriser les routes API

Dans config/packages/api_platform.yaml, assurez-vous que les routes API sont sécurisées :

api_platform:
    mapping:
        paths: ['%kernel.project_dir%/src/Entity']
    patch_formats:
        json: ['application/merge-patch+json']
    swagger:
        versions: [3]
    formats:
        jsonld:
            mime_types: ['application/ld+json']
        json:
            mime_types: ['application/json']

b. Ajouter des contrôles d’accès

Utilisez les annotations ou attributs pour restreindre l’accès aux ressources :

namespace App\Entity;

use ApiPlatform\Core\Annotation\ApiResource;
use Symfony\Component\Security\Core\User\UserInterface;

#[ApiResource(
    collectionOperations: [
        'get' => ['security' => "is_granted('ROLE_USER')"],
        'post' => ['security' => "is_granted('ROLE_ADMIN')"],
    ],
    itemOperations: [
        'get' => ['security' => "is_granted('ROLE_USER')"],
        'put' => ['security' => "is_granted('ROLE_ADMIN')"],
        'delete' => ['security' => "is_granted('ROLE_ADMIN')"],
    ],
)]
class Product
{
    // ...
}

8. Valider les tokens JWT

Utilisez Web-Token/JWT-Framework pour valider les tokens JWT reçus.

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);
    }
}

9. Documentation supplémentaire

Voir Apiplatform TokenValidator Lexik


source:DeepSeek