Authentification Microsoft Entra avec mssql-python

Microsoft Entra ID fournit une authentification basée sur l’identité pour Azure SQL Database, Azure SQL Managed Instance et SQL database dans Microsoft Fabric via le pilote mssql-python. L’authentification Microsoft Entra offre ces fonctionnalités par rapport à l’authentification SQL :

  • Gestion centralisée des identités via Microsoft Entra ID.
  • Authentification basée sur un jeton qui élimine le besoin de mots de passe.
  • Prise en charge des politiques d’accès conditionnel.
  • Identités gérées pour les applications hébergées sur Azure.

Le pilote mssql-python prend en charge sept modes d’authentification Microsoft Entra, tous configurés via le Authentication mot-clé chaîne de connexion.

Modes d’authentification

Définissez le mot-clé Authentication de votre chaîne de connexion sur l’une des valeurs suivantes :

Valeur d’authentification Description
ActiveDirectoryDefault Utilise DefaultAzureCredential, qui essaie automatiquement plusieurs méthodes.
ActiveDirectoryInteractive Connexion interactive basée sur navigateur.
ActiveDirectoryDeviceCode Saisie du code à https://microsoft.com/devicelogin.
ActiveDirectoryPassword Nom d’utilisateur et mot de passe avec Microsoft Entra ID. Obsolescent.
ActiveDirectoryMSI Identité gérée (assignée par le système ou par l’utilisateur).
ActiveDirectoryServicePrincipal Service principal avec un ID client et un secret.
ActiveDirectoryIntegrated Windows intégré à Microsoft Entra ID (Kerberos).

Note

Les ActiveDirectoryDefaultmodes , ActiveDirectoryInteractive, et ActiveDirectoryDeviceCode nécessitent le azure-identity package. Installez-le avec pip install azure-identity.

DefaultAzureCredential

Le mode ActiveDirectoryDefault utilise DefaultAzureCredential du SDK Azure Identity, qui tente ces méthodes d’authentification dans l’ordre suivant :

  1. Variables d'environnement.
  2. Identité des charges de travail pour Kubernetes.
  3. Identité managée.
  4. Informations d’identification Azure CLI.
  5. Informations d’identification Azure PowerShell
  6. Informations d’identification d’Azure Developer CLI.
  7. Navigateur interactif, si activé.

Exemple : Authentification par défaut

L’exemple suivant se connecte à ActiveDirectoryDefault, qui utilise la chaîne DefaultAzureCredential pour trouver automatiquement des informations d’identification valides :

import mssql_python

conn = mssql_python.connect(
    "Server=<server>.database.windows.net;"
    "Database=<database>;"
    "Authentication=ActiveDirectoryDefault;"
    "Encrypt=yes;"
)

cursor = conn.cursor()
cursor.execute("SELECT USER_NAME()")
print(f"Connected as: {cursor.fetchval()}")

Utilisez ce mode pour le développement local car il détecte automatiquement les identifiants Azure CLI. Pour la production, utilisez plutôt un mode d’authentification spécifique (ActiveDirectoryMSI, ActiveDirectoryServicePrincipal) à la place. DefaultAzureCredential Il fait passer par plusieurs fournisseurs d’accréditations à chaque première connexion, ce qui ajoute une latence dont les charges de travail en production n’ont pas besoin.

Authentification interactive

Pour les applications interactives, utilisez l’authentification basée sur navigateur. L’utilisateur doit avoir un compte de base de données créé avec CREATE USER [user@domain.com] FROM EXTERNAL PROVIDER. Pour tous les prérequis, voir Configurer l’authentification Microsoft Entra.

conn = mssql_python.connect(
    "Server=<server>.database.windows.net;"
    "Database=<database>;"
    "Authentication=ActiveDirectoryInteractive;"
    "Encrypt=yes;"
)

Sous Windows, ce mode est délégué au flux interactif natif du pilote ODBC. Sur d'autres plateformes, il utilise l'authentification basée sur navigateur du SDK Azure Identity.

Authentification de code d’appareil

Utilisez l’authentification par code de périphérique pour les environnements sans navigateur, comme les sessions SSH ou les conteneurs. L’utilisateur doit avoir un compte de base de données créé avec CREATE USER [user@domain.com] FROM EXTERNAL PROVIDER. Pour les prérequis, voir Configurer l’authentification Microsoft Entra.

conn = mssql_python.connect(
    "Server=<server>.database.windows.net;"
    "Database=<database>;"
    "Authentication=ActiveDirectoryDeviceCode;"
    "Encrypt=yes;"
)
# Output: To sign in, use a web browser to open https://microsoft.com/devicelogin
# and enter the code XXXXXXX to authenticate.

Suivez l’invite pour vous authentifier dans un navigateur sur un autre appareil.

Authentification du service principal

Utilisez l’authentification du principal de service pour les applications automatisées qui ne nécessitent pas d’interaction utilisateur :

conn = mssql_python.connect(
    "Server=<server>.database.windows.net;"
    "Database=<database>;"
    "Authentication=ActiveDirectoryServicePrincipal;"
    "UID=<client-id>;"       # Application (client) ID
    "PWD=<client-secret>;"   # Client secret
    "Encrypt=yes;"
)

Créer un service principal

  1. Enregistrez une application dans Microsoft Entra ID.
  2. Créer un secret client.
  3. Accordez au principal du service l’accès à votre base de données :
-- In Azure SQL
CREATE USER [app-name] FROM EXTERNAL PROVIDER;
ALTER ROLE db_datareader ADD MEMBER [app-name];
ALTER ROLE db_datawriter ADD MEMBER [app-name];

Tip

Si CREATE USER échoue avec l’erreur 33131 (nom d’affichage en double), utilisez WITH OBJECT_ID pour spécifier l’ID d’objet du principal de service sur la page Applications d’entreprise du portail Azure (et non sur la page d’inscription de l’application) :

CREATE USER [app-name] FROM EXTERNAL PROVIDER
    WITH OBJECT_ID = '<enterprise-app-object-id>';

Pour plus de détails, voir les identifiants Microsoft Entra et les utilisateurs avec des noms d’affichage non uniques.

Identité gérée

Utilisez l’authentification d’identité managée pour les applications hébergées sur Azure, telles qu’App Service, Azure Functions et VM :

Identité gérée attribuée par le système

Connectez-vous en utilisant l’identité attribuée directement à la ressource Azure :

conn = mssql_python.connect(
    "Server=<server>.database.windows.net;"
    "Database=<database>;"
    "Authentication=ActiveDirectoryMSI;"
    "Encrypt=yes;"
)

Identité gérée attribuée par l’utilisateur

Spécifiez l’ID client d’une identité managée attribuée par l’utilisateur dans le UID champ :

conn = mssql_python.connect(
    "Server=<server>.database.windows.net;"
    "Database=<database>;"
    "Authentication=ActiveDirectoryMSI;"
    "UID=<managed-identity-client-id>;"
    "Encrypt=yes;"
)

Configurer l’accès à la base de données

Accordez à l’identité gérée l’accès à votre base de données. Un administrateur Microsoft Entra doit être configuré sur le serveur avant de pouvoir créer des utilisateurs externes. Pour activer l’identité managée sur votre ressource Azure, voir Identités managées pour les ressources Azure.

-- Replace 'my-app-service' with your Azure resource name
CREATE USER [my-app-service] FROM EXTERNAL PROVIDER;
ALTER ROLE db_datareader ADD MEMBER [my-app-service];
ALTER ROLE db_datawriter ADD MEMBER [my-app-service];

Authentification par mot de passe (obsolète)

Important

L’option d’authentification ActiveDirectoryPassword (authentification par mot de passe de Microsoft Entra ID) est dépréciée dans les pilotes Microsoft SQL. Ce flux d’authentification à haut risque est incompatible avec l’authentification multifacteur obligatoire Microsoft Entra (MFA) et peut ne pas fonctionner dans les locataires où l’authentification multifacteur est appliquée. Prévoyez de migrer vers une autre méthode d’authentification Microsoft Entra.

Microsoft Entra ID l’authentification par mot de passe est basée sur l’octroi ROPC (Resource Owner Password Credentials) OAuth 2.0, qui permet à une application de se connecter à l’utilisateur en gérant directement son mot de passe.

Microsoft recommande de ne pas utiliser le flux ROPC, car il n'est pas compatible avec l'authentification multifacteur. Dans la plupart des scénarios, des alternatives plus sécurisées sont disponibles et recommandées. Ce flux nécessite un degré élevé de confiance dans l’application et comporte des risques qui ne sont pas présents dans d’autres flux. Utilisez ce flux uniquement lorsque les flux plus sécurisés ne sont pas viables. Microsoft s’éloigne de ce flux d’authentification à haut risque pour protéger les utilisateurs contre les attaques malveillantes. Pour plus d’informations, consultez Planification de l’authentification multifacteur obligatoire pour Azure.

Lorsqu’un utilisateur est présent lors de la connexion, utilisez l’authentification ActiveDirectoryInteractive ou ActiveDirectoryIntegrated afin que les attributs de piste d’audit de l’utilisateur connecté et des stratégies d’accès conditionnel s’appliquent.

Pour les scénarios de service à service non supervisés, suivez les recommandations relatives aux comptes de service Microsoft Entra :

  • Si votre application s’exécute sur Azure infrastructure, utilisez ActiveDirectoryMSI (ou ActiveDirectoryManagedIdentity dans certains pilotes). Les identités managées éliminent la surcharge liée à la maintenance et à la rotation des secrets et des certificats.
  • Si l'identité managée n'est pas disponible (par exemple, l'application s'exécute en dehors de Azure), utilisez ActiveDirectoryServicePrincipal. Si le pilote le prend en charge, préférez un certificat client plutôt qu’un secret client. Avec un certificat, la clé privée reste sur le client et seule une assertion signée est envoyée à Microsoft Entra pour authentifier le client. Si la clé est stockée sur un support matériel (tel qu’un TPM ou un HSM) ou marquée comme non exportable, elle ne peut pas être extraite sous forme de chaîne, comme on peut le faire avec un secret client.
  • N'utilisez pas de compte d'utilisateur Microsoft Entra en tant que compte de service.

Utilisez l’authentification par mot de passe lorsque vous avez besoin d’un nom d’utilisateur et d’un mot de passe avec un compte Microsoft Entra. L’utilisateur doit avoir un compte de base de données créé avec CREATE USER [user@domain.com] FROM EXTERNAL PROVIDER:

conn = mssql_python.connect(
    "Server=<server>.database.windows.net;"
    "Database=<database>;"
    "Authentication=ActiveDirectoryPassword;"
    "UID=<login@domain.com>;"
    "PWD=<password>;"
    "Encrypt=yes;"
)

Authentification intégrée Windows

Utilisez l’authentification Windows Integrated pour les environnements Windows joints au domaine avec Kerberos. Ce mode exige que votre Active Directory local soit fédéré avec Microsoft Entra ID et qu’un administrateur Microsoft Entra soit configuré sur le serveur :

conn = mssql_python.connect(
    "Server=<server>.database.windows.net;"
    "Database=<database>;"
    "Authentication=ActiveDirectoryIntegrated;"
    "Encrypt=yes;"
)

Ce mode utilise les identifiants Kerberos de l'utilisateur Windows actuel. Sous Linux et macOS, il faut configurer Kerberos manuellement (krb5.conf et un keytab ou un ticket valide). Voir Utiliser l’authentification Active Directory avec SQL Server sur Linux pour la configuration de Kerberos côté client.

Authentification par jeton d’accès

Vous pouvez acquérir des jetons à l’extérieur, par exemple, via un fournisseur de jetons personnalisé ou un cache de jetons partagé. Dans ces cas, utilisez SQL_COPT_SS_ACCESS_TOKEN avec le attrs_before paramètre pour passer directement le jeton. Cette approche contourne le processus intégré d’acquisition de jetons du pilote.

import mssql_python
from azure.identity import DefaultAzureCredential
import struct

def get_token():
    credential = DefaultAzureCredential(
        exclude_interactive_browser_credential=False
    )
    token_bytes = credential.get_token(
        "https://database.windows.net/.default"
    ).token.encode("utf-16le")
    token_struct = struct.pack(
        f'<I{len(token_bytes)}s', len(token_bytes), token_bytes
    )
    return token_struct

SQL_COPT_SS_ACCESS_TOKEN = 1256

conn = mssql_python.connect(
    "Server=<server>.database.windows.net;"
    "Database=<database>;",
    attrs_before={SQL_COPT_SS_ACCESS_TOKEN: get_token()}
)

Important

Lorsqu’on utilise SQL_COPT_SS_ACCESS_TOKEN, la chaîne de connexion ne doit pas inclure UID, PWD, Authentication, ou Trusted_Connection. Le jeton lui-même gère l’authentification.

Choisir un mode d'authentification

Scénario Mode recommandé
Machine de développement ActiveDirectoryDefault(utilise Azure CLI)
Azure App Service / Functions ActiveDirectoryMSI (plus rapide que par défaut)
Azure Kubernetes Service ActiveDirectoryDefault (Identité de la charge de travail)
Scripts automatisés sur site ActiveDirectoryServicePrincipal
Application de bureau interactive ActiveDirectoryInteractive
SSH/conteneur sans navigateur ActiveDirectoryDeviceCode

Troubleshoot

« Échec de la connexion pour l’utilisateur “NT AUTHORITY\ANONYMOUS LOGON” »

Vérifiez que l’utilisateur ou l’identité gérée existe dans la base de données :

CREATE USER [identity-name] FROM EXTERNAL PROVIDER;

« AADSTS700016 : Application non trouvée »

Le principal de service ou l’ID de l’application est incorrect. Vérifiez l’identifiant client et que l’application est enregistrée dans votre locataire Microsoft Entra.

« Endpoint d’identité gérée inaccessible »

  • Vérifiez que l’identité gérée est activée sur la ressource Azure.
  • Pour l’identité attribuée par l’utilisateur, vérifiez que l’ID client est correct.
  • Vérifiez que la ressource dispose d’un accès réseau au point de terminaison d’identité.

Délai d’acquisition du token

ActiveDirectoryDefault utilise DefaultAzureCredential, qui parcourt une chaîne de fournisseurs d’informations d’identification successivement jusqu’à ce que l’un d’eux aboutisse. Cette marche en chaîne ajoute des secondes de latence sur la première connexion, surtout lorsque les fournisseurs antérieurs dans la chaîne (variables d’environnement, identité de charge de travail) échouent avant d’atteindre celui qui fonctionne. En production, spécifiez directement le type d’identifiant pour sauter la chaîne :

# Slow: DefaultAzureCredential tries multiple providers
conn = mssql_python.connect(connection_string, authentication="ActiveDirectoryDefault")

# Fast: Skip directly to managed identity
conn = mssql_python.connect(connection_string, authentication="ActiveDirectoryMSI")