Partage via


Tutoriel : ajouter une connexion à une application web Python Flask

Ce tutoriel constitue la troisième partie de la série de tutoriels qui explique la génération d’une application web Flask Python à partir de zéro et l’intégration de l’authentification en utilisant la plateforme d’identités Microsoft. Dans ce tutoriel, vous ajoutez du code pour authentifier des utilisateurs dans l’application générée.

  • Importer les modules requis et la configuration
  • Créer une instance d’application web Flask
  • Configurer un intergiciel ProxyFix pour un développement local
  • Ajouter du code pour connecter et déconnecter des utilisateurs
  • Définir un point d’entrée pour l’application web

Importer les packages et configurations requis

L’application web que vous générez utilise le package identity.web créé basé sur MSAL Python pour authentifier des utilisateurs dans des applications web. Pour importer le package identity.web, l’infrastructure Flask, les modules Flask, la session Flask et les configurations d’application définies dans le tutoriel précédent, ajoutez le code suivant à app.py :

import identity.web
import requests
from flask import Flask, redirect, render_template, request, session, url_for
from flask_session import Session

import app_config

Dans cet extrait de code, vous importez les redirect, render_template, request, session et url_for : objets et fonctions pour gérer des sessions et des requêtes web dans Flask. Vous pouvez également importer app_config qui contient les paramètres de configuration de votre application.

Créer une instance de l’application web Flask

Après l’importation des modules requis, nous initialisons l’application web en utilisant les configurations dans app-config. Pour créer une instance de votre application web, ajoutez l’extrait de code suivant à app.py :

app = Flask(__name__)
app.config.from_object(app_config)
assert app.config["REDIRECT_PATH"] != "/", "REDIRECT_PATH must not be /"
Session(app)

Dans l’extrait de code ci-dessus, vous initialisez une nouvelle application Flask et chargez les paramètres de configuration en utilisant app.config.from_object(app_config). En utilisant from_object, l’application hérite des configurations spécifiées dans (app_config).

Vous pouvez effectuer une vérification d’assertion pour veiller à ce que le chemin d’accès de redirection de votre application ne soit pas le chemin d’accès racine (“/”). Session(app) initialise la gestion de session pour votre application, ce qui vous permet de gérer des sessions et de stocker des données telles que les états d’authentification des utilisateurs dans plusieurs requêtes.

Configurer un intergiciel ProxyFix pour un développement local

Étant donné que l’exemple d’application web s’exécute sur un hôte local, nous utilisons l’intergiciel ProxyFix pour corriger le schéma d’URL et les informations sur l’hôte dans les en-têtes de demande. Ajoutez le code suivant à app.py pour appliquer ProxyFix :

from werkzeug.middleware.proxy_fix import ProxyFix
app.wsgi_app = ProxyFix(app.wsgi_app, x_proto=1, x_host=1)

Initialiser un objet d’authentification

Vous initialisez ensuite un objet d’authentification en créant une instance de la classe [identity.web.Auth](https://identity-library.readthedocs.io/en/latest/#identity.web.Auth). Vous transmettez également les paramètres session, authority, client_id et client_credential dans le constructeur lors de l’initialisation de l’objet Auth, comme suit :

app.jinja_env.globals.update(Auth=identity.web.Auth)  # Useful in template for B2C
auth = identity.web.Auth(
    session=session,
    authority=app.config["AUTHORITY"],
    client_id=app.config["CLIENT_ID"],
    client_credential=app.config["CLIENT_SECRET"],
)

Dans l’extrait de code, app.jinja_env.globals.update(Auth=identity.web.Auth) ajoute une nouvelle variable globale nommée Auth et lui attribue la valeur identity.web.Auth. Cette opération rend l’application Authaccessible dans tous les modèles rendus par l’application Flask.

Connexion des utilisateurs

Le flux d’autorisation que vous générez dans cette application se compose de deux segments. Dans le premier segment, vous appelez la fonction auth.log_in pour connecter des utilisateurs, comme illustré :

@app.route("/login")
def login():
    return render_template("login.html", version=__version__, **auth.log_in(
        scopes=app_config.SCOPE, # Have user consent to scopes during log-in
        redirect_uri=url_for("auth_response", _external=True), # Optional. If present, this absolute URL must match your app's redirect_uri registered in Microsoft Entra admin center
        prompt="select_account",  # Optional.
        ))

Quand un utilisateur navigue vers l’URL /login dans votre application, Flask appelle la fonction d’affichage qui gère la requête pour afficher le modèle login.html. Dans login(), vous appelez la fonction auth.log_in avec une liste des étendues auxquelles l’utilisateur doit donner son consentement pendant le processus de connexion. Vous fournissez également redirect_uri dans les paramètres, qui doit correspondre à l’URI de redirection de l’application dans le centre d’administration Microsoft Azure.

Vous pouvez également ajouter des paramètres tels que prompt qui contrôle le comportement de l’invite de connexion en demandant une nouvelle authentification, le consentement de l’utilisateur ou une sélection de compte parmi ceux ayant une session active.

Dans le deuxième segment du flux d’autorisation, vous gérez la réponse de l’authentification en appelant la fonction auth.complete_log_in dans le contrôleur redirect_uri, comme illustré :

@app.route(app_config.REDIRECT_PATH)
def auth_response():
    result = auth.complete_log_in(request.args)
    if "error" in result:
        return render_template("auth_error.html", result=result)
    return redirect(url_for("index"))

La fonction complete_log_in() prend le dictionnaire auth_response entrant en tant que paramètres de la requête. En cas de réussite, la fonction redirige l’utilisateur vers la route « index » en utilisant redirect(url_for("index")). Cela signifie que l’utilisateur ayant correctement connecté ses informations est disponible comme dictionnaire contenant les revendications d’un jeton d’ID déjà validé.

Si le résultat contient une erreur, comme déterminé par la condition if "error" in result:, affichez le modèle "auth_error.html" à l’utilisateur.

Déconnecter les utilisateurs

Pour déconnecter des utilisateurs de votre application Flask, appelez la méthode auth.log_out() comme suit :

@app.route("/logout")
def logout():
    return redirect(auth.log_out(url_for("index", _external=True)))

Quand un utilisateur accède à la route d’URL /logout dans l’application, Flask appelle la fonction de déconnexion qui les déconnecte de l’application active. Vous spécifiez également la page vers laquelle les utilisateurs doivent être redirigés une fois déconnectés. Dans l’extrait de code, nous redirigeons les utilisateurs vers la page d’accueil de l’application en utilisant url_for("index", _external=True).

Définir un point d’entrée pour l’application web

Après l’implémentation de la logique de connexion et de déconnexion, ajoutez un point d’entrée à la page d’accueil de votre application en créant la fonction index() comme suit :

@app.route("/")
def index():
    if not (app.config["CLIENT_ID"] and app.config["CLIENT_SECRET"]):
        # This check is not strictly necessary.
        # You can remove this check from your production code.
        return render_template('config_error.html')
    if not auth.get_user():
        return redirect(url_for("login"))
    return render_template('index.html', user=auth.get_user(), version=__version__)

La fonction index() est appelée quand un utilisateur accède à l’URL racine ("/") de l’application. Elle gère les vérifications de configuration et valide l’authentification des utilisateurs avant d’afficher la page d’accueil de l’application. Elle vérifie si l’ID client et la configuration sont manquantes dans la configuration et, si l’une ou les deux valeurs sont manquantes, Flask affiche le modèle "config_error.html".

La fonction appelle également auth.get_user() pour vérifier si l’utilisateur est authentifié ou non. Si l’utilisateur n’est pas authentifié, elle les redirige vers la route "login". En cas d’authentification, Flask affiche le modèle « index.html » et transmet l’objet utilisateur (récupéré de auth.get_user()) pour l’affichage.

Étapes suivantes