Teilen über


Abrufen eines Zugriffstokens (Python)

In diesem Beispiel wird veranschaulicht, wie ein externes Python-Skript aufgerufen wird, um ein OAuth2-Token abzurufen. Ein gültiges OAuth2-Zugriffstoken ist durch die Implementierung des Authentifizierungsstellvertretungs erforderlich.

Voraussetzungen

So führen Sie das Beispiel aus:

  • Installieren Sie Python 3.10 oder höher.
  • Implementieren Sie utils.h/cpp in Ihrem Projekt.
  • Auth.py sollte zu Ihrem Projekt hinzugefügt werden und im gleichen Verzeichnis wie die Binärdateien beim Build vorhanden sein.
  • Vollständiges Microsoft Information Protection (MIP)-SDK-Setup und -Konfiguration. Unter anderem registrieren Sie Ihre Clientanwendung in Ihrem Microsoft Entra-Mandanten. Microsoft Entra-ID stellt eine Anwendungs-ID bereit, die auch als Client-ID bezeichnet wird, die in Ihrer Tokenakquisitionslogik verwendet wird.

Dieser Code ist nicht für den Produktionseinsatz gedacht. Es kann nur für die Entwicklung und das Verständnis von Authentifizierungskonzepten verwendet werden. Das Beispiel ist plattformübergreifend.

sample::auth::AcquireToken()

In dem einfachen Authentifizierungsbeispiel haben wir eine einfache AcquireToken()-Funktion demonstriert, die keine Parameter benötigt und einen fest kodierten Token-Wert zurückgibt. In diesem Beispiel überladen wir AcquireToken(), um Authentifizierungsparameter zu akzeptieren und ein externes Python-Skript aufzurufen, um das Token zurückzugeben.

auth.h

In auth.h wird die Überladung von AcquireToken() ausgeführt, und die überladene Funktion und die aktualisierten Parameter sind wie folgt:

//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.
    }
}

Die ersten drei Parameter werden von Der Benutzereingabe oder hartcodiert in Ihrer Anwendung bereitgestellt. Die letzten beiden Parameter werden vom SDK für den Authentifizierungsdelegat bereitgestellt.

auth.cpp

In auth.cpp fügen wir die überladene Funktionsdefinition hinzu und definieren dann den Code, der zum Aufrufen des Python-Skripts erforderlich ist. Die Funktion akzeptiert alle bereitgestellten Parameter und übergibt sie an das Python-Skript. Das Skript wird ausgeführt und gibt das Token im Zeichenfolgenformat zurück.

#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;
    }
    }
}

Python-Skript

Dieses Skript erwirbt Authentifizierungstoken direkt über die Microsoft Authentication Library (MSAL) für Python. Dieser Code ist nur als Mittel zum Abrufen von Authentifizierungstoken für die Verwendung durch die Beispiel-Apps enthalten und ist nicht für die Verwendung in der Produktion vorgesehen. Das Skript funktioniert nur für Mandanten, die einfache alte Benutzernamen-/Kennwortauthentifizierung unterstützen. MFA oder zertifikatbasierte Authentifizierung werden über dieses Skript nicht unterstützt.

Hinweis

Vor dem Ausführen dieses Beispiels müssen Sie MSAL für Python installieren, indem Sie einen der folgenden Befehle ausführen:

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:])

Aktualisieren von AcquireOAuth2Token

Aktualisieren Sie schließlich die AcquireOAuth2Token-Funktion in AuthDelegateImpl, um die überladene AcquireToken-Funktion aufzurufen. Die Ressourcen- und Autoritäts-URLs werden durch Lesen von challenge.GetResource() und challenge.GetAuthority() abgerufen. Die OAuth2Challenge wird beim Hinzufügen der Engine an den Authentifizierungsdelegat übergeben. Diese Arbeit erfolgt durch das SDK und erfordert keine zusätzliche Arbeit an dem Teil des Entwicklers.

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;
}

Wenn das engine SDK hinzugefügt wird, ruft das SDK die Funktion "AcquireOAuth2Token" auf, übergibt die Abfrage, führt das Python-Skript aus, empfängt ein Token und stellt dann das Token an den Dienst dar.