Token erwerben

Es gibt viele Möglichkeiten, mit MSAL für Python ein Token zu erhalten. Einige erfordern Benutzerinteraktionen, während andere nicht. Der Ansatz zum Abrufen eines Tokens unterscheidet sich je nachdem, ob der Entwickler einen öffentlichen Client (Desktop oder Mobil) oder eine vertrauliche Clientanwendung (Web-App, Web-API oder Daemon wie einen Windows Dienst) erstellt.

Voraussetzungen

Bevor Sie Token mit MSAL Python erwerben, erfahren Sie mehr über clientanwendungstypen.

Benutzerkonto abrufen

Eine App kann ein Token als sich selbst oder im Auftrag eines Benutzers erwerben. Um ein Token im Namen eines Benutzers zu erwerben, muss die App das Konto des Benutzers kennen. MSAL Python stellt die get_accounts Methode zum Abrufen des Benutzerkontos bereit. Diese Methode ist sowohl für PublicClientApplication- als auch für ConfidentialClientApplication-Klassen verfügbar. Die Methode gibt eine Liste von Konten zurück, mit denen sich der Benutzer zuvor angemeldet hat, d. h. im Cache vorhanden ist.

accounts = app.get_accounts(username=user.get("preferred_username"))

Das vom Benutzer für die Anmeldung ausgewählte Konto kann später in acquire_token_silent() verwendet werden, um darin dessen Token zu finden.

Tokenzuweisungsflows

Es gibt mehrere Authentifizierungsflüsse, die zum Abrufen von Token mit MSAL-Python verwendet werden können. Weitere Informationen zu diesen Flüssen finden Sie in der Microsoft Identity Platform Dokumentation.

Warning

Verwenden Sie MSAL immer, um Sicherheitstoken abzurufen und geschützte Web-APIs in Ihren Apps aufzurufen. Es wird nicht empfohlen, Ihre eigene Tokenakquisitionslogik zu implementieren. Diese Flüsse sollen Ihnen helfen, ein besseres Verständnis dafür zu haben, wie dinge funktionieren. Wenn Sie eine Webanwendung schützen, empfehlen wir die Verwendung der Identitätsbibliothek . Diese Bibliothek wird nicht offiziell von Microsoft verwaltet, sondern implementiert die meisten Logik, die Sie zum Abrufen von Token in Web-Apps benötigen.

Interaktiv vs. unbeaufsichtigt

MSAL-Python unterstützt sowohl interaktive als auch automatische Tokenerfassung. Der interaktive Tokenabruf erfordert eine Benutzerinteraktion, während der stille Tokenabruf keine Benutzerinteraktion erfordert. Öffentliche Clients erfordern in der Regel Benutzerinteraktionen, während vertrauliche Clients auf vorab bereitgestellte Anmeldeinformationen wie Zertifikate und geheime Schlüssel angewiesen sind.

Verwenden Sie die Methode acquire_token_silent_with_error, um ein Token im Hintergrund abzurufen. Diese Methode findet ein gültiges Zugriffstoken aus dem Cache oder ein gültiges Aktualisierungstoken aus dem Cache und verwendet es dann automatisch, um ein neues Zugriffstoken einzulösen. Wenn dies nicht der Fall ist, müssen Sie eine interaktive Methode verwenden, um das Token abzurufen.

Wenn es Ihrer App nicht auf den genauen Fehler bei der Token-Aktualisierung beim Nachschlagen im Token-Cache ankommt, dann wird die Methode acquire_token_silent empfohlen.

Eine Beispielverwendung dieser Methode ist wie im folgenden Codeausschnitt dargestellt.

if accounts:
    # If so, you could then somehow display these accounts and let end user choose
    chosen = accounts[0]
    result = app.acquire_token_silent(scopes=["your_scope"], account=chosen)
    
    # At this point, you can save you can update your cache if you are using token caching
    # check result variable, if its None then you should interactively acquire a token
    if not result:
        # So no suitable token exists in cache. Let's get a new one from Microsoft Entra.
        result = app.acquire_token_by_one_of_the_actual_method(..., scopes=["User.Read"])
    
    if "access_token" in result:
        access_token = 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

Für die interaktive Tokenerfassung stehen mehrere Methoden zur Verfügung. Die zu verwendende Methode hängt vom Typ der App ab, die Sie erstellen, und vom Tokenerteilungsfluss, der für Ihr Szenario gilt.

Interaktiver Tokenabruf für öffentliche Clients

Öffentliche Clientanwendungen können einen geheimen Schlüssel nicht sicher speichern und können nur den Benutzer authentifizieren, der mit dem Produkt interagiert. MSAL Python stellt die Logik zur Tokenbeschaffung für öffentliche Anwendungen über PublicClientApplication bereit. Im Folgenden sind die verschiedenen Methoden aufgeführt, die für öffentliche Clientanwendungen zum Abrufen von Token verfügbar sind.

Gerätecodefluss

Der Gerätecodefluss wird verwendet, um Token in Anwendungen abzurufen, die auf Geräten ausgeführt werden, die keinen Zugriff auf einen Webbrowser haben. Hierbei handelt es sich um Anwendungen, die als kopflose Anwendungen bezeichnet werden. Dieser Fluss stellt dem Benutzer eine URL und einen Code bereit. Der Benutzer wechselt zu einem Webbrowser auf einem anderen Gerät, gibt den Code ein und meldet sich an. Bei erfolgreicher Authentifizierung gibt Microsoft Entra ein Token an das browserlose Gerät zurück.

Zuerst rufen Sie die initiate_device_flow Methode auf.

flow = app.initiate_device_flow(scopes=config["scope"])
if "user_code" not in flow:
    raise ValueError(
        "Fail to create device flow. Err: %s" % json.dumps(flow, indent=4))

print(flow["message"])
sys.stdout.flush()  # Some terminal needs this to ensure the message is shown

# Ideally you should wait here, in order to save some unnecessary polling
# input("Press Enter after signing in from another device to proceed, CTRL+C to abort.")

Anschließend übergeben Sie das Flusswörterbuchobjekt an die acquire_token_by_device_flow Methode, um das Token abzurufen. Standardmäßig blockiert diese Methode den aktuellen Thread. Sie können diese Anweisungen befolgen, um die Blockzeit zu verkürzen, oder Sie können das Blockierungsverhalten sogar deaktivieren und dann den Aufruf acquire_token_by_device_flow in Ihrer eigenen angepassten Schleife beibehalten.

result = app.acquire_token_by_device_flow(flow)

if "access_token" in result:
    access_token = result["access_token"]
else:
    print(result.get("error"))  

Eine erfolgreiche Antwort ist ein Wörterbuch mit einem access_token-Schlüssel.

Interaktives Abrufen eines Tokens

MSAL Python ermöglicht es auch öffentlichen Client-Apps (Desktop- und Mobilanwendungen), Token im Namen des Benutzers abzurufen. Der Benutzer meldet sich über die URL der Autorisierungsanforderung über einen Webbrowser an. Legen Sie den Umleitungs-URI Ihrer App für Ihre App-Registrierung im Microsoft Entra Admin Center auf http://localhost fest. Wenn Sie sich bei der Erstellung von PublicClientApplication dafür entscheiden, den Broker zu verwenden, muss Ihre App auch ms-appx-web://Microsoft.AAD.BrokerPlugin/YOUR_CLIENT_ID als Umleitungs-URI registrieren.

result = app.acquire_token_interactive(  # It automatically provides PKCE protection
    scopes=config["scope"])

if "access_token" in result:
    access_token = result["access_token"]
else:
    print(result.get("error"))  

Benutzername und Kennwort

Warning

Diese API ist aufgrund von Sicherheitsrisiken für öffentliche Clientflüsse veraltet und verwendet einen sichereren Fluss. Befolgen Sie diesen Leitfaden für die Migrationsanleitung.

Es wird nicht empfohlen, diesen Ansatz zu verwenden. Es ist auch möglich, ein Token mit einem Benutzernamen und Kennwort abzurufen. MSAL Python stellt die acquire_token_by_username_password Methode für diesen Anwendungsfall bereit. Es wird nicht empfohlen, da die Anwendung einen Benutzer direkt nach seinem Kennwort fragt, bei dem es sich um ein unsicheres Muster handelt.

Es gibt sicherere Flüsse, die Sie verwenden können. Weitere Informationen finden Sie in den Anleitungen zur Benutzernamen- und Kennwortauthentifizierung .

result = app.acquire_token_by_username_password(
    username=config["username"], password=config["password"], scopes=config["scope"])

if "access_token" in result:
    access_token = result["access_token"]
else:
    print(result.get("error"))  

Interaktiver Tokenabruf für vertrauliche Clients

Vertrauliche Clientanwendungen können einen geheimen Schlüssel sicher speichern und sowohl im Namen einer Anwendung als auch im Namen eines bestimmten Benutzers authentifizieren. MSAL Python bietet Entwicklern verschiedene Methoden für den Tokenabruf bei der Entwicklung von ConfidentialClientApplication.

Token für den Client abrufen

Rufen Sie ein Token für die Anwendung selbst mithilfe von client credentials ab, nicht für einen Benutzer. Dies kann beispielsweise in Anwendungen verwendet werden, die Benutzer in Batches und nicht in einem bestimmten Benutzer verarbeiten, z. B. Synchronisierungstools. MSAL Python stellt hierfür die acquire_token_for_client Methode bereit. Seit MSAL Python 1.23 sucht diese Methode automatisch nach einem Token im Cache und sendet nur dann eine Anfrage an den Identitätsanbieter, wenn der Cache keinen Treffer liefert.

result = app.acquire_token_for_client(scopes=config["scope"])

if "access_token" in result:
    access_token = result["access_token"]
else:
    print(result.get("error"))    

Token im Auftrag von abrufen

Verwenden Sie bei Web-Apps oder Web-APIs, die eine andere nachgeschaltete Web-API im Namen des Benutzers aufrufen, den On-Behalf-Of-Flow, um ein Token auf der Grundlage einer Benutzerassertion abzurufen. Beispiel: SAML und JWT. Die aktuelle App ist ein Dienst auf mittlerer Ebene, der mit einem Token aufgerufen wurde, das einen Endbenutzer darstellt. Die aktuelle App kann dieses Token, auch als Benutzer assertion bezeichnet, verwenden, um ein weiteres Token für den Zugriff auf die downstream-Web-API im Namen dieses Benutzers anzufordern. Die Mittlere Ebene-App hat keine Benutzerinteraktion, um die Zustimmung zu erhalten. Informationen dazu, wie Sie die Zustimmung für Ihre mehrschichtige App vorab einholen, finden Sie in der Dokumentation.

Hier ist ein Beispiel für Code, der ein Zugriffstoken mithilfe der acquire_token_on_behalf_of Methode erhält.

def get(self, request): # a web service endpoint receiving a request
    
    scopes = ["your-scopes"]
    downstream_api = "https://your-downstreamapi.com/resource" #your downstream API resource endpoint
    current_access_token = request.headers.get("Authorization", None)
    
    # initialize the app
    app = msal.ConfidentialClientApplication(...) # refer to initialization of the app documentation

    #acquire token on behalf of the user that called this API
    downstream_api_access_token = app.acquire_token_on_behalf_of(
        user_assertion=current_app_access_token.split(' ')[1],
        scopes=_scopes
    )

    if "access_token" in result:
        access_token = result["access_token"]
        # use access_token to call dowstream API e.g
        requests.get(downstream_api, headers={'Authorization': f'Bearer {downstream_api_access_token}'})
    else:
        print(result.get("error")) 

Token über den Autorisierungscodeablauf abrufen

Für Web-Apps, die sich im Namen eines Benutzers authentifizieren, erwerben Sie Token über Autorisierungscode , nachdem der Benutzer sich über die URL der Autorisierungsanforderung anmelden lässt. Dies ist in der Regel der Mechanismus, der von einer Anwendung verwendet wird, mit der der Benutzer sich anmelden und auf Web-APIs für diesen bestimmten Benutzer zugreifen kann.

Zunächst müssen Sie den Authentifizierungscodefluss mithilfe des initiate_auth_code_flowCodes initiieren. Diese Methode akzeptiert unter anderen Parametern eine Umleitungs-URI und Zustandszeichenfolge. Der Wert des Zustandsparameters ist auch in der Tokenantwort enthalten. Wenn dieser Wert nicht vorhanden ist, generiert MSAL Python automatisch eine intern. Der angegebene Umleitungs-URI muss mit dem im Microsoft Entra Admin Center registrierten Umleitungs-URI übereinstimmen. Diese Methode gibt den Authentifizierungscode-Ablauf zurück, bei dem es sich um ein Wörterbuch handelt, das auth_uri und state enthält. Dies auth_uri ist die URL, die der Benutzer besuchen muss, um sich anzumelden.

flow = app.initiate_auth_code_flow(
    scopes=config["scope"], redirect_uri=config["redirect_uri"], state="your-state-value")

if "error" in flow:
    print(flow.get("error"))

# Save the response somewhere e.g in session
session["auth_flow"] = flow

# At this point, the app should guide the user to visit the auth ur (session["auth_flow"]["auth_uri"])

Die Antwort beim Aufrufen der Auth-URI-Endpunkte wird in der Methode acquire_token_by_auth_code_flow verwendet. Der Status ist ein eindeutiger Bezeichner, den Sie verwenden können, um die Antwort vom Autorisierungsserver zu überprüfen. Der Benutzer sollte bei der Anmeldung den Berechtigungsumfängen zustimmen.

# The uth_response value from visiting the auth_uri endpoint is passed as a query string
# You can change this by passing a value to the response_mode in the initiate_auth_code_flow method
try:
    result = app.acquire_token_by_auth_code_flow(session.get("flow", {}), auth_response)
    
    if "access_token" in result:
        access_token = result["access_token"]
    else:
        print(result.get("error"))
except ValueError:  # Usually caused by CSRF
    pass  # Simply ignore them

MSAL Python Tokenzwischenspeicherung

Sowohl öffentliche als auch vertrauliche Clientanwendungen unterstützen die Tokenzwischenspeicherung, die direkt von MSAL Python behandelt wird. Anwendungen sollten versuchen, zuerst ein Token aus dem Cache abzurufen, bevor Sie sich auf andere Mittel verlassen. Weitere Informationen finden Sie unter empfohlenes Muster für die Tokenbeschaffung.

Um den Cache beibehalten zu können, müssen entwickler die Tokencache serialisierungslogik konfigurieren.