Activer l’authentification unique dans Linux natif à l’aide de MSAL Python

Microsoft Authentication Library (MSAL) est un kit de développement logiciel (SDK) qui permet aux applications de faire appel au broker Linux de l’authentification unique Microsoft, un composant Linux distribué indépendamment de la distribution Linux, mais installé à l’aide d’un gestionnaire de packages via sudo apt install microsoft-identity-broker ou sudo dnf install microsoft-identity-broker.

Ce composant agit en tant que répartiteur d’authentification, ce qui permet aux utilisateurs de votre application de bénéficier de l’intégration avec les comptes connus de Linux, tels que le compte que vous avez connecté à vos sessions Linux pour les applications qui consomment à partir du répartiteur.

Le courtier est également inclus comme dépendance d’applications développées par Microsoft (par exemple Portail d'entreprise)). Un exemple de cas où le broker est installé est lorsqu’un ordinateur Linux est inscrit dans le parc d’appareils d’une entreprise via une solution de gestion des terminaux comme Microsoft Intune.

Qu’est-ce qu’un répartiteur ?

Un courtier d’authentification est une application qui s’exécute sur la machine de l’utilisateur et qui gère les échanges d’authentification ainsi que la maintenance des jetons pour les comptes connectés. Le système d’exploitation Linux utilise l’authentification unique Microsoft pour Linux comme courtier d’authentification. Il présente de nombreux avantages pour les développeurs et les clients, notamment :

  • Active l’authentification unique : permet aux applications de simplifier la façon dont les utilisateurs s’authentifient avec Microsoft Entra ID et protège les jetons d’actualisation de Microsoft Entra ID contre l’exfiltration et l’utilisation abusive
  • Sécurité renforcée. De nombreuses améliorations de sécurité sont fournies avec le répartiteur, sans avoir à mettre à jour la logique d’application.
  • Prise en charge des fonctionnalités. Grâce au broker, les développeurs peuvent accéder à de nombreuses fonctionnalités avancées du système d’exploitation et des services.
  • Intégration du système. Les applications qui utilisent le broker en mode Plug-and-Play avec le sélecteur de comptes intégré permettent à l’utilisateur de choisir rapidement un compte existant au lieu de ressaisir les mêmes identifiants à plusieurs reprises.
  • Protection des jetons. L’authentification unique Microsoft pour Linux garantit que les jetons d’actualisation sont liés à un appareil.

Comment choisir d’utiliser le répartiteur ?

  1. Dans la bibliothèque MSAL Python, nous avons introduit l’indicateur enable_broker_on_linux, qui active le broker aussi bien sur WSL que sur Linux autonome.
    • Si votre objectif est d’activer la prise en charge du broker uniquement sur WSL dans Azure CLI, vous pouvez envisager de modifier le code de l’application Azure CLI afin de n’activer l’indicateur enable_broker_on_wsl que sur WSL.
    • Si vous écrivez une application multiplateforme, vous devez également utiliser enable_broker_on_windows, comme indiqué dans l’article Utilisation de MSAL Python avec le Gestionnaire de comptes web.
    • Vous pouvez définir n’importe quelle combinaison des paramètres d’opt-in suivants sur true :
Indicateur d’activation Si l’application s’exécute sur L’application a enregistré cet URI de redirection en tant que plateforme Desktop dans le portail Azure.
enable_broker_on_windows Windows 10+ ms-appx-web://Microsoft.AAD.BrokerPlugin/your_client_id
activer_broker_sur_WSL WSL ms-appx-web://Microsoft.AAD.BrokerPlugin/your_client_id
enable_broker_on_mac Mac avec Portail d'entreprise installé msauth.com.msauth.unsignedapp://auth
enable_broker_on_linux Linux avec Intune installé https://login.microsoftonline.com/common/oauth2/nativeclient (DOIT être activé)
  1. Votre application doit prendre en charge les URI de redirection spécifiques au répartiteur. Pour Linux plus précisément, l’URL de l’URI de redirection doit être :

    https://login.microsoftonline.com/common/oauth2/nativeclient
    
  2. Pour utiliser le répartiteur, vous devez installer les packages liés au répartiteur en plus du MSAL principal à partir de PyPI :

    pip install "msal[broker]>=1.33.0b1,<2"
    
  3. Une fois configuré, vous pouvez appeler acquire_token_interactive pour acquérir un jeton.

    result = app.acquire_token_interactive(["User.ReadBasic.All"],
                        parent_window_handle=app.CONSOLE_WINDOW_HANDLE)
    

Paramètres de prise en charge des courtiers

Les paramètres suivants sont disponibles pour configurer la prise en charge du répartiteur dans MSAL Python. Ces paramètres peuvent être passés au PublicClientApplication constructeur ou à la acquire_token_interactive méthode.

Paramètres : Type Description
enable_broker_on_windows boolean Ce paramètre n’est effectif que si votre application s’exécute sur Windows 10+. Ce paramètre est défini par défaut sur None, ce qui signifie que MSAL n’utilise pas de répartiteur.

New in MSAL Python 1.25.0.
activer_broker_sur_WSL boolean Ce paramètre est effectif uniquement si votre application s’exécute sur WSL. Ce paramètre est défini par défaut sur None, ce qui signifie que MSAL n’utilise pas de répartiteur.

New in MSAL Python 1.25.0.
enable_broker_on_mac boolean Ce paramètre n’est effectif que si votre application s’exécute sur Mac avec Portail d'entreprise installé. Ce paramètre est défini par défaut sur None, ce qui signifie que MSAL n’utilise pas de répartiteur.

New in MSAL Python 1.31.0.
enable_broker_on_linux boolean Ce paramètre n’est effectif que si votre application s’exécute sur Linux avec Intune installé. Ce paramètre est défini par défaut sur None, ce qui signifie que MSAL n’utilise pas de répartiteur.

New in MSAL Python 1.33.0.
parent_window_handle int FACULTATIF

Remarques concernant parent_window_handle

Le parent_window_handle paramètre est requis même si sur Linux il n’est pas utilisé. Pour les applications GUI, l’emplacement de l’invite de connexion est déterminé ad hoc et ne peut pas être lié à une fenêtre spécifique. Dans une prochaine mise à jour, ce paramètre sera utilisé pour déterminer la fenêtre parente réelle .

Pathologie Description
L’application ne souhaite pas utiliser un répartiteur il n’est pas nécessaire de spécifier une parent_window_handle
L’application choisit d’utiliser un répartiteur parent_window_handle est obligatoire
L’application est une application GUI s’exécutant sur Windows ou le système Mac doit fournir son descripteur de fenêtre, afin que la fenêtre de connexion apparaisse au-dessus de votre fenêtre
L’application est une application console s’exécutant sur Windows ou le système Mac peut utiliser un espace réservé PublicClientApplication.CONSOLE_WINDOW_HANDLE
L’application est destinée à être une application multiplateforme L’application doit utiliserenable_broker_on_windows, comme indiqué dans l’article Using MSAL Python with Web Account Manager.

Les comportements de repli de la prise en charge du broker dans MSAL Python

MSAL va effectuer une erreur ou revenir en mode silencieux aux flux non répartiteurs.

  1. MSAL ignorera le paramètre enable_broker_… et contourner le broker pour ces flux d’authentification dont on sait qu’ils ne sont PAS pris en charge par le broker. Cela inclut ADFS, B2C, etc.. Pour d’autres scénarios « could-use-broker », consultez ci-dessous.

  2. MSAL renvoie une erreur lorsque le développeur d’application a choisi d’utiliser le broker, mais qu’un package « mid-tier » de dépendance directe n’est pas installé. Le message d’erreur indique au développeur de l’application de déclarer la dépendance correcte msal[broker]. Nous avons une erreur ici, car l’erreur est exploitable pour les développeurs d’applications.

  3. MSAL « désactive » silencieusement le broker et bascule vers le mode sans broker lorsque cette option est activée, que la dépendance est installée, mais que son initialisation échoue. Nous prévoyons que cela se produit sur un appareil dont le système d’exploitation est trop ancien ou que le composant broker sous-jacent n’est pas disponible en quelque sorte. Un développeur d’application ou l’utilisateur final ne peuvent pas faire grand-chose ici. Finalement, la stratégie d’accès conditionnel force l’utilisateur à basculer vers un autre appareil.

  4. MSAL renvoie une erreur lorsque le broker est activé, installé et initialisé, mais que la ou les demandes de jeton suivantes échouent.

Important

Si les packages liés au répartiteur ne sont pas installés et que vous essayez d’utiliser le répartiteur d’authentification, vous obtiendrez une erreur : ImportError: You need to install dependency by: pip install "msal[broker]>=1.xx,<2".

Note

Le parent_window_handle paramètre est requis même si sur Linux il n’est pas utilisé. Pour les applications GUI, l’emplacement de l’invite de connexion est déterminé ad hoc et ne peut pas être lié à une fenêtre spécifique. Dans une prochaine mise à jour, ce paramètre sera utilisé pour déterminer la fenêtre parente réelle .

Mise en cache de jeton

Le répartiteur d’authentification gère l’actualisation et la mise en cache des jetons d’accès. Vous n’avez pas besoin de configurer la mise en cache personnalisée.

Création d’un exemple d’application

Vous trouverez un exemple d’application qui montre comment utiliser MSAL Python avec le répartiteur d’authentification sur Linux dans le référentiel MSAL Python GitHub. L’exemple d’application se trouve dans le samples/console_app répertoire et inclut des exemples d’utilisation du répartiteur pour l’authentification.

Inscription d’application

Mettez à jour votre inscription d’application dans le portail Azure pour inclure l’URI de redirection spécifique au répartiteur pour Linux :

https://login.microsoftonline.com/common/oauth2/nativeclient

Dépendances Linux

Tout d’abord, vérifiez si python3 est installé sur votre distribution Linux.

python3 --version

Si ce n’est pas le cas, installez-le à l’aide du gestionnaire de package pour votre distribution.

Pour installer sur la distribution Linux basée sur Debian/Ubuntu :

sudo add-apt-repository -y universe
sudo apt update
sudo apt install python3 python3-pip libwebkit2gtk-4.1-dev -y

Dépendances de Python

Pour utiliser le répartiteur, vous devez installer les packages liés au répartiteur en plus du MSAL principal à partir de PyPI :

pip install "msal[broker]>=1.33.0b1,<2"

Créer un projet

Une fois configuré, vous pouvez appeler acquire_token_interactive pour acquérir un jeton.

import sys  # For simplicity, we'll read config file from 1st CLI param sys.argv[1]
import json
import logging
import requests
import msal

# Optional logging
# logging.basicConfig(level=logging.DEBUG)

var_authority = "https://login.microsoftonline.com/common"
var_client_id = "your-client-id-here"  # Replace with your app's client ID
var_username = "your-username-here"  # Replace with your username, e.g., "
var_scope = ["User.ReadBasic.All"]
# Removed unused variable to avoid confusion


# Create a preferably long-lived app instance which maintains a token cache (Default cache is in memory only).
app = msal.PublicClientApplication(
    var_client_id, 
    authority=var_authority,
    enable_broker_on_windows=True,
    enable_broker_on_wsl=True
    )

# The pattern to acquire a token looks like this.
result = None

# Firstly, check the cache to see if this end user has signed in before
accounts = app.get_accounts(username=var_username)
if accounts:
    logging.info("Account(s) exists in cache, probably with token too. Let's try.")
    result = app.acquire_token_silent(var_scope, account=accounts[0])

if not result:
    logging.info("No suitable token exists in cache. Let's get a new one from AAD.")
    
    result = app.acquire_token_interactive(var_scope,parent_window_handle=app.CONSOLE_WINDOW_HANDLE)
    
if "access_token" in result:
    print("Access token is: %s" % result['access_token'])

else:
    print(result.get("error"))
    print(result.get("error_description"))
    print(result.get("correlation_id"))  # You may need this when reporting a bug
    if 65001 in result.get("error_codes", []):  # Not mean to be coded programatically, but...
        # AAD requires user consent for U/P flow
        print("Visit this to consent:", app.get_authorization_request_url(config["scope"]))