Se rendre au contenu

Comment connecter une application Python Flask avec OpenID Connect et Keycloak ?

12 juin 2025 par
Comment connecter une application Python Flask avec OpenID Connect et Keycloak ?
Ariovis

OpenID Connect est une couche d'identité construite par-dessus le protocole OAuth 2.0. Elle permet aux applications de vérifier l'identité des utilisateurs en se basant sur une authentification effectuée par un fournisseur externe. Cela est particulièrement utile lorsqu’on souhaite sécuriser des applications sans avoir à gérer soi-même les identifiants des utilisateurs. Keycloak est une solution open source de gestion des identités et des accès (IAM) qui facilite la mise en place d’un fournisseur OpenID Connect robuste.

Dans cet article, nous allons expliquer comment connecter votre propre application Python Flask à n’importe quel fournisseur OpenID Connect, ainsi que comment configurer le vôtre avec Keycloak. Vous allez configurer un serveur Keycloak, enregistrer un client OIDC, et construire une application Flask simple qui authentifie les utilisateurs via Keycloak en utilisant des protocoles standards de l'industrie.

À la fin de ce guide, vous aurez :

  • Une instance fonctionnelle de Keycloak exécutée dans Docker
  • Une application Flask sécurisée avec OpenID Connect
  • Un flux complet de connexion et de déconnexion
  • Une architecture de projet Flask structurée et évolutive

Cette configuration est idéale pour les développeurs souhaitant ajouter une authentification à leurs applications web Python en s’appuyant sur des standards modernes de gestion d’identité.


Pré-requis

Avant de commencer, voici les prérequis de base pour utiliser ce guide :

Avec ces deux outils en main, nous pouvons démarrer notre projet en toute sérénité.


Comprendre ce qu’est OpenID Connect

Si vous êtes déjà familier avec OpenID Connect, vous pouvez passer cette section. Si ce n’est pas le cas, ou si vous souhaitez un rappel du concept, cette partie vous offrira un aperçu rapide de son fonctionnement, de son utilité, et du rôle qu’il joue dans la sécurisation de votre application.

OpenID Connect est donc construit sur le protocole ouvert OAuth2. C'est une norme web mondialement adoptée et utilisée par des acteurs technologiques majeurs tels que Google, Microsoft et Apple. Elle permet la vérification de l'identité des utilisateurs en s'appuyant sur les services d'identité et d'authentification d'un fournisseur externe.

Cette approche élimine le besoin d'une base de données d'utilisateurs dédiée, simplifiant la manière dont vous implémentez l'authentification et l'autorisation dans vos applications.

Entièrement interopérable, OpenID Connect fonctionne via une interface HTTP RESTful avec un formatage JSON. Il y a de fortes chances que vous utilisiez déjà cette norme quotidiennement : chaque fois que vous cliquez sur un bouton « Se connecter avec Google » au lieu de saisir des identifiants distincts, vous utilisez OpenID Connect.

Maintenant, si vous n'êtes pas non plus familier avec le protocole OAuth2, voici le flux d'informations détaillé qui se produit lorsque vous utilisez OpenID Connect.




Lorsque vous vous connectez à un service via OpenID Connect, la première étape vous redirige vers le fournisseur d'identité (par exemple, Google, Microsoft, Apple) pour que vous puissiez vous authentifier avec votre compte. Une fois votre identité vérifiée, ce fournisseur vous fournit en retour un code d'autorisation. Votre service utilise ensuite ce code pour l'échanger contre un jeton d'identité (ID Token) auprès du fournisseur. Ce jeton représente votre identité vérifiée.

Désormais, chaque fois que le service a besoin d'informations sur votre profil, il interroge le fournisseur d'identité en utilisant ce jeton. Le fournisseur renvoie alors les informations nécessaires, et le service vous donne accès aux ressources appropriées en fonction de votre identité.

Ce processus est connu sous le nom de flux de code d'autorisation (Authorization Code Flow) d'OpenID Connect. Grâce à cette conception, le jeton d'identité n'est jamais directement exposé côté client (le "frontend"), ce qui réduit considérablement les risques d'attaques et de vols d'identité.


Qu'est ce que Keycloak ? 

Keycloak est une solution de gestion des identités et des accès entièrement open-source qui offre un support tout-en-un pour l'authentification et l'autorisation. Conçu pour la flexibilité, il permet aux développeurs de sécuriser leurs applications avec un effort minimal, en proposant des fonctionnalités prêtes à l'emploi comme le single sign-on (SSO), la connexion via les réseaux sociaux et la gestion des utilisateurs.

Nous utiliserons Keycloak pour jouer le rôle de fournisseur d'identité dans notre projet. Grâce à lui, vous pourrez créer et gérer vos utilisateurs, personnaliser entièrement le flux d'authentification et lier vos utilisateurs à tous vos projets plus rapidement. Cette solution est également légère et évolutive grâce à sa capacité de clustering, si vous pré prévoyez de l'implémenter sur des projets plus importants.

Toutes les configurations se feront via cette console d'administration, donc aucune compétence spécialisée n'est requise pour l'utiliser.


Configurez Keycloak

La première étape de ce guide est la configuration de Keycloak. Pour cela, nous utiliserons Docker car cela facilite l'étape d'installation.

Pour fonctionner, Keycloak a besoin de stocker ses données dans une base de données. Pour cet article, nous utiliserons Postgres, mais vous pouvez utiliser n'importe quelle base de données de la liste suivante :

Pour orchestrer toute la configuration, nous utiliserons le fichier docker-compose.yaml suivant :


Ce fichier est la configuration de votre environnement Keycloak et Postgres. Assurez-vous de modifier les paramètres d'utilisateur et de mot de passe selon vos préférences.

Exécutez la commande suivante pour lancer une instance basique de Keycloak sur votre machine :

docker-compose up

Une fois que le conteneur est entièrement démarré, vous pouvez accéder à la console d'administration à l'adresse suivante : http://localhost:8080. Vous pouvez vous connecter à la console d'administration et devriez arriver sur cette page :

Depuis cette console, vous pouvez administrer toutes vos connexions, vos utilisateurs, vos clients, et bien plus encore…

Nous allons d'abord créer un "realm" pour notre application. Pour cela, vous pouvez cliquer sur la liste des realms en haut à gauche. Comme nous n'avons pas de configuration existante, nous allons simplement en créer un vide. Pour cet article, je le nommerai demo-openid-connect.

Dans Keycloak, un "realm" est comme un conteneur qui regroupe tous les utilisateurs, applications et paramètres pour un projet ou un environnement spécifique.

L'étape suivante consiste à configurer un client OpenID que Python utilisera pour se connecter à Keycloak. Dans votre nouveau "realm" créé, allez dans "Clients" et créez-en un nouveau.

Vous devrez configurer les paramètres suivants :

  • Type de client : OpenID Connect Vous avez le choix entre SAML et OpenID Connect ; dans cet article, nous nous concentrerons sur OpenID Connect.
  • ID client : 7f3c2e10-8c1a-4c71-89f2-f0bb72e536f4 C'est l'ID de votre client, il sera nécessaire plus tard pour s'y connecter. Vous pouvez choisir n'importe quoi ; pour cet exemple, j'ai choisi un UUID aléatoire.
  • Nom : open-id-client Le nom de votre client. Il sert uniquement à identifier votre client sur Keycloak, vous pouvez choisir n'importe quoi.
  • Authentification client : activer (basculer sur true) Permet d'autoriser le flux OpenID sur ce client.
  • URL racine : http://localhost:8081 L'URL racine de votre application. Pour cet exemple, nous utiliserons une instance locale sur le port 8081.
  • URL de la page d'accueil : / La page d'accueil de l'application. Puisque notre application sera à l'URL racine, nous mettrons simplement /. Si vous souhaitez l'exécuter sous un chemin spécifique, vous pouvez le modifier.
  • URL de redirection valides : * Pour cet exemple, nous autoriserons n'importe quelle URL de notre domaine à servir de redirection depuis notre client. En production, vous devriez la remplacer par une URL plus spécifique pour restreindre votre client à votre seule application.

Enfin, vous devrez configurer un secret pour votre client. Pour cela, allez dans l'onglet "Credentials" (Identifiants) et copiez-le. Il devrait ressembler à ceci : 961jZtg26dDrLcUacShPyYRvUEAhQEA4.

Ce secret est la preuve que votre application utilisera pour s'authentifier auprès de Keycloak. Vous devez faire attention à ne pas le partager et à le sauvegarder dans un endroit inaccessible, comme un gestionnaire de secrets ou un fichier d'environnement.

Vous pouvez aussi configurer des rôles personnalisés pour votre application si vous en avez besoin :

Passage à Python

Notre Keycloak est maintenant prêt à être utilisé par notre application Python. Nous allons maintenant construire notre application Python. Pour cela, nous utiliserons Flask, mais sachez que vous pouvez utiliser n'importe quel autre serveur HTTP.


Qu'est-ce que Flask ?

Flask est un framework web minimaliste écrit en Python. Il vous permet de lancer rapidement un serveur web et d'exposer des points d'accès (endpoints) pour votre application. Il est léger, simple à utiliser et bien adapté à la création d'API REST ou de petits services web.

Voici un exemple basique d'une application Flask :

Dans cet exemple, nous lançons un serveur web et créons un point d'accès (endpoint) sur le chemin /. Pour exécuter cette application, il suffit de l'enregistrer dans un fichier (par exemple, app.py) et de l'exécuter avec Python :

  • python -m pip install Flask
  • python app.py

Vous pouvez maintenant vous rendre sur votre navigateur web à l'adresse http://localhost/. Vous devriez y voir le texte "Hello, world!".

C'est tout ! Vous avez construit un petit serveur web. Nous pouvons maintenant commencer à créer notre application.

La puissance de Flask réside dans sa capacité à rendre des templates HTML et à y injecter vos propres données. Nous allons légèrement modifier notre script pour faire un exemple basique, mais d'abord, nous devrons organiser un peu notre projet.

Si vous avez suivi toutes les étapes, vous devriez avoir quelque chose comme ceci :

La structure recommandée que nous utiliserons pour un projet Flask est la suivante :

Description :

  • App : Ce dossier est la racine de votre projet. Tout ce qui est lié à Flask y sera placé.
  • __init__.py : Cette convention de nom de fichier de Python nous permet d'utiliser les chemins de dossiers directement comme chemins pour les fichiers Python qu'ils contiennent, comme cela fonctionnerait avec index.html sur le web. Celui qui se trouve à la racine contiendra la configuration de votre application Flask.
  • routes.py : Ce fichier contiendra tous les points d'accès (endpoints) du dossier et implémentera la logique associée. Dans des projets plus importants, vous pourriez placer la logique dans un fichier services.py dédié.
  • config.py : Ce fichier contiendra la configuration de votre application Flask et importera vos variables d'environnement.
  • Extensions : Ce dossier contiendra tous les scripts Python dont vous avez besoin dans votre application et qui ne sont pas directement liés à Flask, comme une connexion à une base de données par exemple.
  • Main : Ce dossier contient tous les points d'accès principaux de notre application.
  • Templates : Ce dossier contient tous les fichiers HTML qui seront utilisés par Flask et nécessiteront une injection de données.
  • Static : Ce dossier contient toutes les données statiques de notre projet, telles que les images, les feuilles de style CSS, les scripts, et plus encore.

Pour exécuter notre application, nous allons maintenant utiliser la commande suivante :

flask --app app run --debug --port=8081

Le contenu de chaque fichier ressemblera à ceci :

app/__init__.py

config.py

app/main/__init__.py

app/main/routes.py

app/template/index.html

app/base/base.html

Il y a beaucoup de nouveaux concepts ici :

Premièrement, les Blueprints. Dans Flask, vous pouvez créer des Blueprints pour regrouper vos points d'accès (endpoints). Chaque dossier contenant des routes représentera un Blueprint dans notre projet. Pour l'instant, nous n'avons besoin que du Blueprint principal.

Deuxièmement, les Templates. Comme mentionné précédemment, vous pouvez utiliser des templates dans Flask, créés à partir de HTML et de Jinja2. Pour en savoir plus, vous pouvez consulter la documentation de Flask. Dans ce projet, nous avons deux fichiers HTML :

  • base.html : Il contiendra tout ce que nous voulons partager entre nos pages, comme l'importation de Tailwind dans notre cas.
  • index.html : Il contiendra le contenu de la page d'accueil de notre application.

Pour lancer votre application nouvellement créée, vous pouvez utiliser la commande suivante :

  • flask —app app run —debug

Vous pouvez voir le résultat de votre application à l'adresse http://localhost:8081/.

Maintenant que vous êtes familiarisé avec Flask et l'organisation de projet, nous allons commencer à développer le connecteur OIDC pour Keycloak !


Implémenter OIDC avec Flask

Nous allons maintenant implémenter OpenID Connect dans notre application. Pour cela, nous utiliserons la bibliothèque Python oic.

Tout d'abord, nous allons placer nos variables d'environnement dans notre configuration. Pour cela, vous devrez ajouter ce qui suit à votre fichier config.py.

.env

Remplacez les variables appropriées par vos propres données. AUTHORITY représente l'URL de base de votre serveur Keycloak OpenID. REDIRECT_URI représente le point d'accès que nous utiliserons à l'avenir pour notre flux OpenID Connect.


La classe d'identité

Pour réutiliser facilement notre script d'identité qui gérera la logique OpenID, nous allons créer une classe statique.

Voici la base de notre classe :

app/extentions/identity.py

Cette classe définit un client OpenID et le configure avec notre environnement. Les méthodes provider_config et store_registration_info fourniront les informations nécessaires à notre client pour récupérer toutes les données dont il a besoin afin de connaître les URL des points d'accès de notre Keycloak.

Nous allons maintenant implémenter chaque étape du flux OIDC :


1. Obtenir l'URL de connexion

Pour se connecter, l'utilisateur devra construire une URL contenant toutes les informations sur la requête de connexion. Cette URL est spécifique à chaque connexion et doit fournir à Keycloak :

  • L'URL de redirection de la requête
  • La méthode d'authentification et le type de réponse
  • Les scopes auxquels l'utilisateur souhaite accéder
  • Un état (state) et un nonce, deux chaînes aléatoires pour identifier la requête

Pour cela, nous utiliserons la puissance de la bibliothèque oic, ce qui rendra cette tâche beaucoup plus rapide.

app/extensions/identity.py



2. Obtenir le jeton d'authentification

L'étape suivante du flux OpenID Connect consiste à récupérer le jeton de l'utilisateur auprès du fournisseur. Pour cela, nous allons une fois de plus utiliser la bibliothèque oic. Cette fois, nous n'avons qu'à envoyer les informations suivantes au fournisseur :

  • Le code fourni par l'utilisateur, preuve de son authentification auprès du fournisseur.
  • L'URL de redirection depuis laquelle le serveur a récupéré le code.

app/extensions/identity.py

Dans cette fonction, nous allons faire une requête au fournisseur avec toutes les informations fournies par notre client. Nous devons créer le Grant et l'ajouter nous-mêmes au client pour que la requête soit réussie. Ce jeton récupéré sera la preuve d'identité de notre utilisateur.

Nous avons maintenant tout ce dont nous avons besoin pour commencer à implémenter nos points d'accès (endpoints) et tester notre OIDC.


3. Tester le flux d'authentification

Pour cela, nous allons créer des routes dédiées dans un nouveau dossier avec les deux fichiers suivants :

app/auth/__init__.py

app/auth/routes.py

Dans ce code, nous définissons deux points d'accès (endpoints) qui seront utilisés par nos clients pour suivre le flux d'identification. Le premier redirigera notre client vers le fournisseur avec les informations appropriées. Le second récupérera le jeton depuis le rappel (callback) du fournisseur.

Juste avant de tester notre programme, nous avons besoin de deux petites mises à jour de notre application :

  • Premièrement, nous devons ajouter notre nouveau Blueprint à notre application.

app/__init__.py

Ensuite, nous devons ajouter des paramètres à notre configuration pour utiliser les sessions Flask.

config.py

Vous devrez également installer Flask-Session comme dépendance. Vous pouvez utiliser la commande suivante :

pip install Flask-Session

En vous rendant sur http://localhost:8081/auth/login, vous devriez être redirigé vers votre Keycloak et voir ceci :

Pour finaliser notre test, nous devrons ajouter un utilisateur dans la console Keycloak. Allez dans l'onglet "Utilisateurs" et ajoutez-en un :

Vous devrez également définir un mot de passe depuis l'interface. Pour cela, allez dans l'onglet "Credentials"(Identifiants). Retournez ensuite à votre application et connectez-vous avec votre utilisateur. Si tout s'est bien passé, vous devriez être redirigé vers votre page d'accueil.

Si vous tentez de saisir des informations différentes de celles précédemment utilisées, vous remarquerez que rien ne change. Le flux de connexion a fonctionné, mais nous n'accédons pas encore aux informations de l'utilisateur. Ce sera la dernière étape de notre guide. Si vous êtes curieux, vous pouvez ouvrir la console de développement de votre navigateur et constater qu'un cookie de session a été créé par notre flux d'authentification. Pour des raisons de sécurité, nous avons choisi de masquer le véritable jeton d'accès au client et de ne lui donner qu'une référence aux données. Cela permet d'éviter les attaques telles que le vol de jetons via une vulnérabilité XSS dans votre application.


4. Obtenir les informations de l'utilisateur

Tout ce dont nous avons besoin maintenant est de pouvoir récupérer les informations de notre utilisateur lorsqu'il est connecté à notre application. Pour cela, nous pouvons appeler le point d'accès des informations utilisateur de notre fournisseur avec la méthode do_user_info_request de notre client oic. Le code ressemblera à ceci :

app/extensions/identity.py

Pour utiliser cette méthode, nous devons fournir le jeton à la requête. Pour cela, nous avons choisi d'utiliser une propriété qui tentera d'obtenir l'access_token à partir de la session. Puisque nous utilisons cette classe uniquement avec des méthodes statiques, nous devrons définir une propriété statique.

app/extensions/identity.py

À chaque fois que nous accédons à notre access_token, le script tentera de récupérer le jeton de la session ou ne retournera rien.

Nous pouvons maintenant mettre à jour notre page d'accueil pour afficher les informations de notre utilisateur :

app/main/routes.py

app/templates/index.html

Et voilà ! L'application affiche enfin correctement les informations de notre utilisateur. 🥳

Pour aller plus loin

Bien que nous ayons terminé notre flux d'authentification, vous souhaiterez peut-être ajouter des fonctionnalités supplémentaires telles que la déconnexion ou la protection des points d'accès (endpoints) par authentification.

Pour cela, nous ajouterons ce qui suit à notre classe Identity :

app/extenstions/identity.py

Ce code utilisera la bibliothèque oic pour terminer la session sur Keycloak et videra la session côté client. Vous pouvez maintenant appeler cette fonction dans votre code ou créer un point d'accès (endpoint) dédié comme ceci :

app/auth/routes.py

Pour la deuxième partie, la meilleure façon de sécuriser facilement n'importe quel point d'accès (endpoint) est d'écrire un décorateur qui effectuera toutes les vérifications pour vous :

app/extensions/identity.py


Il vous suffira d'apposer ce décorateur sur n'importe quelle route que vous souhaitez protéger, et elle sera inaccessible au client s'il ne s'est pas connecté au préalable. Il ajoutera également les informations de l'utilisateur comme paramètre optionnel à votre fonction lors de l'appel. De cette façon, vous pourrez récupérer directement les informations de l'utilisateur sans avoir à appeler vous-même la fonction get_user_info. Exemple :

app/auth/routes.py

Si vous souhaitez en savoir plus sur les décorateurs et comment les utiliser, vous pouvez consulter le tutoriel suivant : https://realpython.com/primer-on-python-decorators/.

En suivant ce tutoriel, vous avez réussi à configurer Keycloak comme fournisseur OpenID Connect et à l'intégrer à une application Python Flask. Vous avez créé un flux d'authentification sécurisé, récupéré les informations de l'utilisateur et ajouté une fonctionnalité de déconnexion. Vous avez également appris à structurer une application Flask pour l'évolutivité et la maintenabilité.

Pour les environnements de production, n'oubliez pas de :

  • Sécuriser correctement les secrets et les sessions
  • Activer HTTPS
  • Utiliser une validation stricte des URI de redirection
  • Implémenter la gestion de l'expiration et du rafraîchissement des jetons

Avec ces bases en place, vous êtes prêt à étendre votre application avec des API protégées, un contrôle d'accès basé sur les rôles, et bien plus encore. 🚀

🔗 lien vers le code de l'article

Partager cet article
Nos blogs