Files
varlog/_cache/articles/5510b12a-d647-4b1a-90ba-d421a4927ff7.json
T
2026-05-15 10:37:48 +02:00

1 line
14 KiB
JSON
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{"uuid":"5510b12a-d647-4b1a-90ba-d421a4927ff7","slug":"configurer-un-client-oauth-2-0-dans-keycloak-guide-complet","title":"Configurer un client OAuth 2.0 / OIDC dans Keycloak","author":"cedric@abonnel.fr","published":true,"published_at":"2025-05-16 23:33","created_at":"2025-05-16 23:33:31","updated_at":"2026-05-12 20:39:53","revisions":[{"n":1,"date":"2026-05-12 20:39:53","comment":"Contenu modifié","title":"Configurer un client OAuth 2.0 / OIDC dans Keycloak"}],"cover":"","files_meta":[],"external_links":[],"seo_title":"","seo_description":"","og_image":"","category":"informatique","content":"# Configurer un client OAuth 2.0 / OIDC dans Keycloak\n\n*Keycloak* est une solution open source de gestion des identités et des accès (IAM). Cet article décrit la configuration d'un client OAuth 2.0 / OpenID Connect dans Keycloak, en détaillant les options importantes et en montrant comment restreindre l'accès aux utilisateurs ou groupes autorisés.\n\n> **Note de version.** L'interface d'administration a été refondue à partir de Keycloak 19. La notion d'**Access Type** (`confidential` / `public` / `bearer-only`) a disparu au profit des toggles **Client authentication** et **Authorization**. Ce guide suit l'UI actuelle (Keycloak 24+).\n\n---\n\n## 1. Prérequis\n\n- Une instance Keycloak fonctionnelle (version 24 ou supérieure recommandée).\n- Des droits d'administration sur un **realm**.\n- Une application destinée à s'authentifier via OAuth 2.0 / OIDC.\n- TLS activé sur Keycloak et sur l'application cliente (obligatoire en production).\n\n---\n\n## 2. Qu'est-ce qu'un client dans Keycloak ?\n\nDans Keycloak, un **client** représente une application ou un service qui interagit avec le serveur d'authentification, soit pour authentifier des utilisateurs, soit pour obtenir des informations sur eux, soit pour protéger ses propres ressources. Il peut s'agir d'une application web, d'une API, d'une application mobile, d'un service interne ou d'un partenaire tiers.\n\nChaque client est rattaché à un **realm** (l'espace logique d'authentification) et identifié par un `client_id` unique. Cet identifiant est transmis lors de toute demande d'authentification ou d'obtention de jeton.\n\nLa configuration d'un client définit notamment :\n\n- les flux OAuth 2.0 autorisés (`authorization_code`, `client_credentials`, etc.) ;\n- la capacité ou non du client à conserver un secret (client *confidentiel* vs *public*) ;\n- les URI de redirection acceptées et les origines CORS ;\n- la durée de vie des jetons et la composition des claims (mappers) ;\n- les politiques d'autorisation associées (rôles, groupes, attributs).\n\n---\n\n## 3. Création du client\n\n1. Se connecter à la **Keycloak Admin Console**.\n2. Sélectionner le realm cible.\n3. Menu **Clients** > **Create client**.\n\n### Étape « General settings »\n\n| Champ | Valeur recommandée | Description |\n| ------------------ | ----------------------------------- | ---------------------------------------------------------------------------- |\n| **Client type** | `OpenID Connect` | Protocole utilisé. Choisir `SAML` uniquement pour des intégrations SAML 2.0. |\n| **Client ID** | `myapp-client` | Identifiant unique du client dans le realm. Apparaît dans les jetons (`azp`). |\n| **Name** | `My Application` | Libellé d'affichage (facultatif, peut être localisé). |\n| **Description** | Texte libre | Aide à la maintenance. |\n\n### Étape « Capability config »\n\n| Toggle | Valeur recommandée | Détail |\n| ------------------------------- | ---------------------------------------- | ------------------------------------------------------------------------------------------ |\n| **Client authentication** | `ON` pour un backend, `OFF` pour un SPA | `ON` rend le client **confidentiel** (un secret est généré). `OFF` rend le client **public**. |\n| **Authorization** | `OFF` | À activer uniquement si l'on souhaite utiliser le moteur d'autorisations fine (RBAC/ABAC) de Keycloak. |\n| **Standard flow** | `ON` | Active le flux Authorization Code, à utiliser systématiquement. |\n| **Direct access grants** | `OFF` | Flux `password` — déconseillé par OAuth 2.1, à n'utiliser que pour des outils internes legacy. |\n| **Implicit flow** | `OFF` | Déprécié par OAuth 2.1, ne pas activer. |\n| **Service accounts roles** | `ON` si client_credentials | Permet au client de récupérer un jeton pour son propre compte (machine-to-machine). |\n| **OAuth 2.0 Device Auth Grant** | `OFF` (sauf besoin spécifique) | Pour les appareils sans navigateur (TV, CLI sans IHM locale). |\n| **OIDC CIBA Grant** | `OFF` (sauf besoin spécifique) | Authentification déportée (canal hors-bande). |\n\n### Étape « Login settings »\n\n| Champ | Exemple | Description |\n| ----------------------- | -------------------------------- | --------------------------------------------------------------------------------------------------- |\n| **Root URL** | `https://app.example.com` | URL de base de l'application. Permet d'utiliser des chemins relatifs dans les champs suivants. |\n| **Home URL** | `/` | Page par défaut après login. |\n| **Valid redirect URIs** | `https://app.example.com/*` | URI exactes autorisées pour la redirection après authentification. Éviter les wildcards larges. |\n| **Valid post logout redirect URIs** | `https://app.example.com/*` | URI autorisées pour la redirection après déconnexion (RP-Initiated Logout). |\n| **Web origins** | `https://app.example.com` | Origines CORS autorisées. La valeur `+` reprend automatiquement les redirect URIs ; `*` est à proscrire. |\n| **Admin URL** | `https://app.example.com` | Utilisé pour les notifications backchannel (logout global, push not-before). |\n\n> **Bonne pratique.** Les redirect URIs doivent être en `https://` en production (sauf `http://localhost` pour le développement). Spécifier des chemins aussi précis que possible plutôt qu'un wildcard `/*`.\n\n---\n\n## 4. Authentification du client (Credentials)\n\nL'onglet **Credentials** n'apparaît que si **Client authentication** est sur `ON`. Plusieurs méthodes sont disponibles :\n\n| Méthode | Usage |\n| -------------------------------- | ---------------------------------------------------------------------- |\n| **Client Id and Secret** | Secret partagé classique. À stocker dans un coffre-fort (Vault, env vars chiffrées). |\n| **Signed JWT** | Le client signe un JWT d'assertion avec sa clé privée. Plus sûr qu'un secret. |\n| **Signed JWT with Client Secret** | Variante symétrique (HMAC). |\n| **X.509 Certificate** | mTLS — recommandé pour les contextes à forte exigence (FAPI, banque). |\n\n> **Important.** Le secret ne doit jamais être commité dans Git ni embarqué dans un binaire distribué. Pour un projet où les secrets vivent dans `config/.env`, ne commiter que `config/.env.example`.\n\n---\n\n## 5. Types de clients\n\nDepuis Keycloak 19, le « type » est déduit de la combinaison des toggles. La terminologie OAuth reste utile :\n\n| Type | Configuration Keycloak | Cas d'usage |\n| --------------- | ------------------------------------------------------------------- | ------------------------------------------------------------ |\n| **Confidentiel** | `Client authentication = ON` | Backend serveur (PHP, Node, Java…), BFF, service-to-service. |\n| **Public** | `Client authentication = OFF` + `Standard flow = ON` + **PKCE** | SPA (React, Vue, Angular), application mobile, CLI native. |\n| **Service account** | `Client authentication = ON` + `Service accounts roles = ON` | Communication machine-to-machine (`grant_type=client_credentials`). |\n\nLe type « bearer-only » a été retiré : pour une API qui se contente de valider des jetons sans déclencher d'authentification, créer un client confidentiel et n'activer **aucun** flux.\n\n---\n\n## 6. PKCE — recommandé pour tous les clients\n\n**PKCE** (*Proof Key for Code Exchange*, RFC 7636) protège le flux Authorization Code contre l'interception du code d'autorisation. Conçu initialement pour les clients publics, il est aujourd'hui recommandé pour **tous les clients**, y compris confidentiels, et obligatoire dans OAuth 2.1.\n\nActivation dans **Advanced** > **Proof Key for Code Exchange Code Challenge Method** > `S256`.\n\n> Ne jamais utiliser `plain` ; `S256` est la seule valeur acceptable.\n\n---\n\n## 7. Restreindre l'accès aux utilisateurs ou groupes\n\nPar défaut, tout utilisateur du realm peut se connecter via n'importe quel client. Deux approches permettent de restreindre cet accès.\n\n### Approche 1 — Authentification basée sur les rôles (simple)\n\n1. Créer un rôle client dédié, par exemple `app-user`, dans l'onglet **Roles** du client.\n2. Assigner ce rôle aux utilisateurs ou groupes autorisés (Users > *user* > Role mapping, ou Groups > *group* > Role mapping).\n3. Dans **Authentication** > **Flows**, ajouter une exécution `Conditional - User Role` au flux Browser, configurée avec le rôle requis et `Required`.\n\nCette méthode bloque l'authentification elle-même : un utilisateur sans le rôle ne pourra pas se connecter au client.\n\n### Approche 2 — Authorization Services (granulaire)\n\nÀ utiliser pour gérer des permissions plus fines (ressources, scopes, conditions).\n\n1. Activer **Authorization** sur le client.\n2. Onglet **Authorization** > **Policies** > créer une *Group Policy* ou *Role Policy* listant les utilisateurs/groupes autorisés.\n3. Onglet **Permissions** > créer une *Scope-Based Permission* ou *Resource-Based Permission* liée à la policy.\n4. Côté application, utiliser l'endpoint **UMA** ou l'adaptateur Keycloak pour évaluer les permissions.\n\n### Approche 3 — Limiter le client scope « roles »\n\nDans **Client scopes** > `roles` > **Scope**, désactiver *Full scope allowed* et n'autoriser que les rôles pertinents. Cela réduit la taille des jetons et limite ce que le client peut « voir » des rôles utilisateurs.\n\n---\n\n## 8. Client scopes et mappers\n\nLes **client scopes** déterminent les claims présents dans les jetons (`access_token` et `id_token`).\n\n- Les scopes **Default** sont systématiquement ajoutés à chaque jeton.\n- Les scopes **Optional** ne sont ajoutés que si l'application les demande via le paramètre `scope=` lors de l'authentification.\n\nPour exposer les groupes d'un utilisateur dans le token :\n\n1. Créer un client scope `groups` (ou réutiliser celui existant).\n2. Ajouter un mapper de type **Group Membership** :\n - *Token Claim Name* : `groups`\n - *Full group path* : `OFF` (sauf besoin d'arborescence)\n - *Add to ID token / Access token / Userinfo* : selon l'usage.\n3. Attacher le scope au client (Default ou Optional).\n\n---\n\n## 9. Réglages avancés à connaître\n\n| Section | Réglage | Recommandation |\n| ---------------------------------- | -------------------------------- | ---------------------------------------------------------------- |\n| **Advanced > Fine grain OpenID Connect configuration** | `Access Token Signature Algorithm` | `RS256` (par défaut) ou `PS256` pour FAPI. |\n| **Advanced > Advanced settings** | `Proof Key for Code Exchange` | `S256`. |\n| **Advanced > Advanced settings** | `Front channel logout` | `OFF` sauf si l'application implémente correctement la spec OIDC Front-Channel Logout. |\n| **Advanced > Advanced settings** | `Backchannel logout URL` | Renseigner pour une déconnexion globale propre. |\n| **Advanced > Token Lifespan** | `Access Token Lifespan` | Court (515 min). Le refresh token prend le relais. |\n| **Sessions** | `Client Session Idle / Max` | Aligner sur la politique de session de l'organisation. |\n\nPour appliquer automatiquement un ensemble cohérent de règles, utiliser les **Client Policies** du realm (profils pré-définis `oauth-2-1-for-confidential-client` et `oauth-2-1-for-public-client`).\n\n---\n\n## 10. Checklist de sécurité\n\n- [ ] `Client authentication = ON` pour tout client qui peut conserver un secret.\n- [ ] PKCE `S256` activé.\n- [ ] Implicit flow et Direct access grants désactivés.\n- [ ] Redirect URIs en `https://` et sans wildcard inutile.\n- [ ] Web origins explicites (pas de `*`).\n- [ ] Secret stocké dans un coffre-fort, jamais commité.\n- [ ] Access token court (≤ 15 min) et refresh token rotatif.\n- [ ] Accès restreint via rôle dédié ou Authorization Services.\n- [ ] *Full scope allowed* désactivé si les rôles transportés doivent être limités.\n- [ ] Logout backchannel ou front-channel configuré.\n\n---\n\n## Conclusion\n\nLa configuration d'un client OAuth 2.0 dans Keycloak repose sur quelques choix structurants — confidentiel ou public, flux activés, PKCE, restriction d'accès — qui ont chacun des implications de sécurité fortes. S'aligner sur OAuth 2.1 (PKCE systématique, pas d'implicit flow, pas de password grant) et utiliser les **Client Policies** pour appliquer ces règles à l'échelle du realm évite la plupart des configurations à risque.","featured":false,"tags":[]}