Obtenir un jeton d’accès (Python)
Cet exemple montre comment appeler un script Python externe pour obtenir un jeton OAuth2. Un jeton d’accès OAuth2 valide est requis par l’implémentation du délégué de l’authentification.
Prérequis
Pour exécuter l’exemple :
- Installez Python 3.10 ou version ultérieure.
- Implémentez utils.h/cpp dans votre projet.
- Auth.py doit être ajouté à votre projet et être présent dans le même répertoire que les fichiers binaires au moment du build.
- Terminez la configuration et l’installation et la configuration du Kit de développement logiciel (SDK) Microsoft Protection des données (MIP). Entre autres tâches, vous inscrivez votre application cliente dans votre locataire Microsoft Entra. Microsoft Entra ID fournit un ID d’application, également appelé ID client, qui est utilisé dans votre logique d’acquisition de jeton.
Ce code n’est pas destiné à un usage en production. Il peut uniquement être utilisé pour le développement et la compréhension des concepts d’authentification. L’exemple est multiplateforme.
sample::auth::AcquireToken()
Dans l’exemple d’authentification simple, nous avons montré une fonction AcquireToken()
simple qui n’a pris aucun paramètre et a retourné une valeur de jeton codée en dur. Dans cet exemple, nous surchargeons AcquireToken() pour accepter les paramètres d’authentification et appeler un script Python externe pour retourner le jeton.
auth.h
Dans auth.h, AcquireToken()
est surchargé et la fonction surchargée et les paramètres mis à jour sont les suivants :
//auth.h
#include <string>
namespace sample {
namespace auth {
std::string AcquireToken(
const std::string& userName, //A string value containing the user's UPN.
const std::string& password, //The user's password in plaintext
const std::string& clientId, //The Azure AD client ID (also known as Application ID) of your application.
const std::string& resource, //The resource URL for which an OAuth2 token is required. Provided by challenge object.
const std::string& authority); //The authentication authority endpoint. Provided by challenge object.
}
}
Les trois premiers paramètres sont fournis par l’entrée utilisateur ou codées en dur dans votre application. Les deux derniers paramètres sont fournis par le kit de développement logiciel (SDK) au délégué de l’authentification.
auth.cpp
Dans auth.cpp, nous ajoutons la définition de fonction surchargée, puis définissons le code nécessaire pour appeler le script Python. La fonction accepte tous les paramètres fournis et les passe au script Python. Le script s’exécute et retourne le jeton au format de chaîne.
#include "auth.h"
#include "utils.h"
#include <fstream>
#include <functional>
#include <memory>
#include <string>
using std::string;
using std::runtime_error;
namespace sample {
namespace auth {
//This function implements token acquisition in the application by calling an external Python script.
//The Python script requires username, password, clientId, resource, and authority.
//Username, Password, and ClientId are provided by the user/developer
//Resource and Authority are provided as part of the OAuth2Challenge object that is passed in by the SDK to the AuthDelegate.
string AcquireToken(
const string& userName,
const string& password,
const string& clientId,
const string& resource,
const string& authority) {
string cmd = "python";
if (sample::FileExists("auth.py"))
cmd += " auth.py -u ";
else
throw runtime_error("Unable to find auth script.");
cmd += userName;
cmd += " -p ";
cmd += password;
cmd += " -a ";
cmd += authority;
cmd += " -r ";
cmd += resource;
cmd += " -c ";
// Replace <application-id> with the Application ID provided during your Azure AD application registration.
cmd += (!clientId.empty() ? clientId : "<application-id>");
string result = sample::Execute(cmd.c_str());
if (result.empty())
throw runtime_error("Failed to acquire token. Ensure Python is installed correctly.");
return result;
}
}
}
Script Python
Ce script acquiert des jetons d’authentification directement via la bibliothèque d’authentification Microsoft (MSAL) pour Python. Ce code est inclus uniquement comme moyen d’acquérir des jetons d’authentification à utiliser par les exemples d’applications et n’est pas destiné à être utilisé en production. Le script fonctionne uniquement sur les locataires qui prennent en charge l’ancienne authentification par nom d’utilisateur/mot de passe. L’authentification MFA ou basée sur des certificats n’est pas prise en charge via ce script.
Remarque
Avant d’exécuter cet exemple, vous devez installer MSAL pour Python en exécutant l’une des commandes suivantes :
pip install msal
pip3 install msal
import getopt
import sys
import json
import re
from msal import PublicClientApplication
def printUsage():
print('auth.py -u <username> -p <password> -a <authority> -r <resource> -c <clientId>')
def main(argv):
try:
options, args = getopt.getopt(argv, 'hu:p:a:r:c:')
except getopt.GetoptError:
printUsage()
sys.exit(-1)
username = ''
password = ''
authority = ''
resource = ''
clientId = ''
for option, arg in options:
if option == '-h':
printUsage()
sys.exit()
elif option == '-u':
username = arg
elif option == '-p':
password = arg
elif option == '-a':
authority = arg
elif option == '-r':
resource = arg
elif option == '-c':
clientId = arg
if username == '' or password == '' or authority == '' or resource == '' or clientId == '':
printUsage()
sys.exit(-1)
# ONLY FOR DEMO PURPOSES AND MSAL FOR PYTHON
# This shouldn't be required when using proper auth flows in production.
if authority.find('common') > 1:
authority = authority.split('/common')[0] + "/organizations"
app = PublicClientApplication(client_id=clientId, authority=authority)
result = None
if resource.endswith('/'):
resource += ".default"
else:
resource += "/.default"
# *DO NOT* use username/password authentication in production system.
# Instead, consider auth code flow and using a browser to fetch the token.
result = app.acquire_token_by_username_password(username=username, password=password, scopes=[resource])
print(result['access_token'])
if __name__ == '__main__':
main(sys.argv[1:])
Mettre à jour AcquireOAuth2Token
Enfin, mettez à jour la fonction AcquireOAuth2Token
dans AuthDelegateImpl
pour appeler la fonction surchargée AcquireToken
. Les URL de ressource et d’autorité sont obtenues en lisant challenge.GetResource()
et challenge.GetAuthority()
. La OAuth2Challenge
est transmise au délégué de l’authentification lorsque le moteur est ajouté. Ce travail est effectué par le Kit de développement logiciel (SDK) et ne nécessite aucun travail supplémentaire de la part du développeur.
bool AuthDelegateImpl::AcquireOAuth2Token(
const mip::Identity& /*identity*/,
const OAuth2Challenge& challenge,
OAuth2Token& token) {
//call our AcquireToken function, passing in username, password, clientId, and getting the resource/authority from the OAuth2Challenge object
string accessToken = sample::auth::AcquireToken(mUserName, mPassword, mClientId, challenge.GetResource(), challenge.GetAuthority());
token.SetAccessToken(accessToken);
return true;
}
Lorsque le engine
kit de développement logiciel (SDK) appelle la fonction AcquireOAuth2Token, en passant le défi, en exécutant le script Python, en recevant un jeton, puis en présentant le jeton au service.