Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Von Bedeutung
Ab dem 1. Mai 2025 steht Azure AD B2C nicht mehr für neue Kunden zur Verfügung. Weitere Informationen finden Sie in unseren HÄUFIG gestellten Fragen.
In diesem Artikel erfahren Sie, wie Sie azure Active Directory B2C (Azure AD B2C)-Authentifizierung in Ihrer eigenen Python-Webanwendung hinzufügen. Mit Azure AD B2C-Benutzerflüssen können Sie sich anmelden, abmelden, Profil aktualisieren und Kennwort zurücksetzen. In diesem Artikel wird die Microsoft Authentication Library (MSAL) für Python verwendet, um das Hinzufügen der Authentifizierung zu Ihrer Python-Webanwendung zu vereinfachen.
Ziel dieses Artikels ist es, die Beispielanwendung zu ersetzen, die Sie in der Konfiguration der Authentifizierung in einer Python-Beispielwebanwendung mithilfe von Azure AD B2C mit Ihrer eigenen Python-Anwendung verwendet haben.
In diesem Artikel wird Python 3.9+ und Flask 2.1 verwendet, um eine einfache Web-App zu erstellen. Die Ansichten der Anwendung verwenden Jinja2-Vorlagen.
Voraussetzungen
- Führen Sie die Schritte unter Konfigurieren der Authentifizierung in einer Python-Beispielwebanwendung mithilfe von Azure AD B2C aus. Sie erstellen Azure AD B2C-Benutzerflüsse und registrieren eine Webanwendung im Azure-Portal.
- Installieren von Python 3.9 oder höher
- Visual Studio Code oder ein anderer Code-Editor
- Installieren der Python-Erweiterung für Visual Studio Code
Schritt 1: Erstellen des Python-Projekts
Erstellen Sie in Ihrem Dateisystem einen Projektordner für dieses Lernprogramm, wie
my-python-web-app.Verwenden Sie Ihr Terminal, um das Verzeichnis in Ihren Python-App-Ordner zu wechseln, beispielsweise
cd my-python-web-app.Führen Sie den folgenden Befehl aus, um eine virtuelle Umgebung zu erstellen und zu aktivieren, die auf Ihrem aktuellen Interpreter basiert
.venv.Aktualisieren Sie pip in der virtuellen Umgebung, indem Sie den folgenden Befehl im Terminal ausführen:
python -m pip install --upgrade pipUm die Flask-Debugfeatures zu aktivieren, wechseln Sie Flask in den
developmentModus der Entwicklungsumgebung. Weitere Informationen zum Debuggen von Flask-Apps finden Sie in der Flask-Dokumentation.Öffnen Sie den Projektordner in VS Code, indem Sie den
code .Befehl ausführen, oder öffnen Sie VS Code, und wählen Sie den Ordner " Datei>öffnen" aus.
Schritt 2: Installieren von App-Abhängigkeiten
Erstellen Sie unter Ihrem Web App-Stammordner die requirements.txt Datei. Die Anforderungsdatei listet die Pakete auf, die mithilfe der Pip-Installation installiert werden sollen. Fügen Sie der datei requirements.txt den folgenden Inhalt hinzu:
Flask>=2
werkzeug>=2
flask-session>=0.3.2,<0.5
requests>=2,<3
msal>=1.7,<2
Installieren Sie in Ihrem Terminal die Abhängigkeiten, indem Sie die folgenden Befehle ausführen:
Schritt 3: Erstellen von App-UI-Komponenten
Flask ist ein einfaches Python-Framework für Webanwendungen, das die Grundlagen für das URL-Routing und das Seitenrendering bereitstellt. Es verwendet Jinja2 als Vorlagenmodul, um den Inhalt Ihrer App zu rendern. Weitere Informationen finden Sie in der Vorlagen-Designerdokumentation. In diesem Abschnitt fügen Sie die erforderlichen Vorlagen hinzu, die die grundlegenden Funktionen Ihrer Web-App bereitstellen.
Schritt 3.1 Erstellen einer Basisvorlage
Eine Basisseitenvorlage in Flask enthält alle freigegebenen Teile einer Reihe von Seiten, einschließlich Verweise auf CSS-Dateien, Skriptdateien usw. Basisvorlagen definieren auch ein oder mehrere Blocktags, die andere Vorlagen, die die Basis erweitern, voraussichtlich außer Kraft setzen. Ein Blocktag wird sowohl durch {% block <name> %} und {% endblock %} in der Basisvorlage als auch in der erweiterten Vorlage abgegrenzt.
Erstellen Sie im Stammordner Ihrer Web-App den templates Ordner. Erstellen Sie im Vorlagenordner eine Datei mit dem Namen base.html, und fügen Sie dann den folgenden Inhalt hinzu:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
{% block metadata %}{% endblock %}
<title>{% block title %}{% endblock %}</title>
<!-- Bootstrap CSS file reference -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-0evHe/X+R7YkIZDRvuzKMRqM+OrBnVFBL6DOitfPri4tjfHxaWutUpFmBp4vmVor" crossorigin="anonymous">
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
<div class="container-fluid">
<a class="navbar-brand" href="{{ url_for('index')}}">Python Flask demo</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse"
data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false"
aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
<li class="nav-item">
<a class="nav-link active" aria-current="page" href="{{ url_for('index')}}">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{{ url_for('graphcall')}}">Graph API</a>
</li>
</ul>
</div>
</div>
</nav>
<div class="container body-content">
<br />
{% block content %}
{% endblock %}
<hr />
<footer>
<p>Powered by MSAL Python {{ version }}</p>
</footer>
</div>
</body>
</html>
Schritt 3.2 Erstellen der Web-App-Vorlagen
Fügen Sie die folgenden Vorlagen unter dem Vorlagenordner hinzu. Diese Vorlagen erweitern die base.html Vorlage:
index.html: die Startseite der Web-App. Die Vorlagen verwenden die folgende Logik: Wenn sich ein Benutzer nicht anmeldet, wird die Anmeldeschaltfläche gerendert. Wenn sich ein Benutzer anmeldet, werden die Ansprüche des Zugriffstokens dargestellt, ein Link zur Bearbeitung des Profils bereitgestellt und eine Graph-API aufgerufen.
{% extends "base.html" %} {% block title %}Home{% endblock %} {% block content %} <h1>Microsoft Identity Python Web App</h1> {% if user %} <h2>Claims:</h2> <pre>{{ user |tojson(indent=4) }}</pre> {% if config.get("ENDPOINT") %} <li><a href='/graphcall'>Call Microsoft Graph API</a></li> {% endif %} {% if config.get("B2C_PROFILE_AUTHORITY") %} <li><a href='{{_build_auth_code_flow(authority=config["B2C_PROFILE_AUTHORITY"])["auth_uri"]}}'>Edit Profile</a></li> {% endif %} <li><a href="/logout">Logout</a></li> {% else %} <li><a href='{{ auth_url }}'>Sign In</a></li> {% endif %} {% endblock %}graph.html: Veranschaulicht, wie eine REST-API aufgerufen wird.
{% extends "base.html" %} {% block title %}Graph API{% endblock %} {% block content %} <a href="javascript:window.history.go(-1)">Back</a> <!-- Displayed on top of a potentially large JSON response, so it will remain visible --> <h1>Graph API Call Result</h1> <pre>{{ result |tojson(indent=4) }}</pre> <!-- Just a generic json viewer --> {% endblock %}auth_error.html: Behandelt Authentifizierungsfehler.
{% extends "base.html" %} {% block title%}Error{% endblock%} {% block metadata %} {% if config.get("B2C_RESET_PASSWORD_AUTHORITY") and "AADB2C90118" in result.get("error_description") %} <!-- See also https://learn.microsoft.com/azure/active-directory-b2c/active-directory-b2c-reference-policies#linking-user-flows --> <meta http-equiv="refresh" content='0;{{_build_auth_code_flow(authority=config["B2C_RESET_PASSWORD_AUTHORITY"])["auth_uri"]}}'> {% endif %} {% endblock %} {% block content %} <h2>Login Failure</h2> <dl> <dt>{{ result.get("error") }}</dt> <dd>{{ result.get("error_description") }}</dd> </dl> <a href="{{ url_for('index') }}">Homepage</a> {% endblock %}
Schritt 4: Konfigurieren Ihrer Web-App
Erstellen Sie im Stammordner Ihrer Web-App eine Datei mit dem Namen app_config.py. Diese Datei enthält Informationen zu Ihrem Azure AD B2C-Identitätsanbieter. Die Web-App verwendet diese Informationen, um eine Vertrauensstellung mit Azure AD B2C herzustellen, Benutzer anzumelden und abzumelden, Token zu erwerben und zu validieren. Fügen Sie der Datei den folgenden Inhalt hinzu:
import os
b2c_tenant = "fabrikamb2c"
signupsignin_user_flow = "B2C_1_signupsignin1"
editprofile_user_flow = "B2C_1_profileediting1"
resetpassword_user_flow = "B2C_1_passwordreset1" # Note: Legacy setting.
authority_template = "https://{tenant}.b2clogin.com/{tenant}.onmicrosoft.com/{user_flow}"
CLIENT_ID = "Enter_the_Application_Id_here" # Application (client) ID of app registration
CLIENT_SECRET = "Enter_the_Client_Secret_Here" # Application secret.
AUTHORITY = authority_template.format(
tenant=b2c_tenant, user_flow=signupsignin_user_flow)
B2C_PROFILE_AUTHORITY = authority_template.format(
tenant=b2c_tenant, user_flow=editprofile_user_flow)
B2C_RESET_PASSWORD_AUTHORITY = authority_template.format(
tenant=b2c_tenant, user_flow=resetpassword_user_flow)
REDIRECT_PATH = "/getAToken"
# This is the API resource endpoint
ENDPOINT = '' # Application ID URI of app registration in Azure portal
# These are the scopes you've exposed in the web API app registration in the Azure portal
SCOPE = [] # Example with two exposed scopes: ["demo.read", "demo.write"]
SESSION_TYPE = "filesystem" # Specifies the token cache should be stored in server-side session
Aktualisieren Sie den obigen Code mit Ihren Azure AD B2C-Umgebungseinstellungen, wie im Abschnitt Konfigurieren der Beispiel-Webanwendung des Artikels Authentifizierung in einer Beispiel-Python-Webanwendung konfigurieren erläutert.
Schritt 5: Hinzufügen des Web-App-Codes
In diesem Abschnitt fügen Sie die Flask-Ansichtsfunktionen und die MSAL-Bibliotheksauthentifizierungsmethoden hinzu. Fügen Sie unter dem Stammordner Ihres Projekts eine Datei app.py mit dem folgenden Code hinzu:
import uuid
import requests
from flask import Flask, render_template, session, request, redirect, url_for
from flask_session import Session # https://pythonhosted.org/Flask-Session
import msal
import app_config
app = Flask(__name__)
app.config.from_object(app_config)
Session(app)
# This section is needed for url_for("foo", _external=True) to automatically
# generate http scheme when this sample is running on localhost,
# and to generate https scheme when it is deployed behind reversed proxy.
# See also https://flask.palletsprojects.com/en/1.0.x/deploying/wsgi-standalone/#proxy-setups
from werkzeug.middleware.proxy_fix import ProxyFix
app.wsgi_app = ProxyFix(app.wsgi_app, x_proto=1, x_host=1)
@app.route("/anonymous")
def anonymous():
return "anonymous page"
@app.route("/")
def index():
#if not session.get("user"):
# return redirect(url_for("login"))
if not session.get("user"):
session["flow"] = _build_auth_code_flow(scopes=app_config.SCOPE)
return render_template('index.html', auth_url=session["flow"]["auth_uri"], version=msal.__version__)
else:
return render_template('index.html', user=session["user"], version=msal.__version__)
@app.route("/login")
def login():
# Technically we could use empty list [] as scopes to do just sign in,
# here we choose to also collect end user consent upfront
session["flow"] = _build_auth_code_flow(scopes=app_config.SCOPE)
return render_template("login.html", auth_url=session["flow"]["auth_uri"], version=msal.__version__)
@app.route(app_config.REDIRECT_PATH) # Its absolute URL must match your app's redirect_uri set in AAD
def authorized():
try:
cache = _load_cache()
result = _build_msal_app(cache=cache).acquire_token_by_auth_code_flow(
session.get("flow", {}), request.args)
if "error" in result:
return render_template("auth_error.html", result=result)
session["user"] = result.get("id_token_claims")
_save_cache(cache)
except ValueError: # Usually caused by CSRF
pass # Simply ignore them
return redirect(url_for("index"))
@app.route("/logout")
def logout():
session.clear() # Wipe out user and its token cache from session
return redirect( # Also logout from your tenant's web session
app_config.AUTHORITY + "/oauth2/v2.0/logout" +
"?post_logout_redirect_uri=" + url_for("index", _external=True))
@app.route("/graphcall")
def graphcall():
token = _get_token_from_cache(app_config.SCOPE)
if not token:
return redirect(url_for("login"))
graph_data = requests.get( # Use token to call downstream service
app_config.ENDPOINT,
headers={'Authorization': 'Bearer ' + token['access_token']},
).json()
return render_template('graph.html', result=graph_data)
def _load_cache():
cache = msal.SerializableTokenCache()
if session.get("token_cache"):
cache.deserialize(session["token_cache"])
return cache
def _save_cache(cache):
if cache.has_state_changed:
session["token_cache"] = cache.serialize()
def _build_msal_app(cache=None, authority=None):
return msal.ConfidentialClientApplication(
app_config.CLIENT_ID, authority=authority or app_config.AUTHORITY,
client_credential=app_config.CLIENT_SECRET, token_cache=cache)
def _build_auth_code_flow(authority=None, scopes=None):
return _build_msal_app(authority=authority).initiate_auth_code_flow(
scopes or [],
redirect_uri=url_for("authorized", _external=True))
def _get_token_from_cache(scope=None):
cache = _load_cache() # This web app maintains one cache per session
cca = _build_msal_app(cache=cache)
accounts = cca.get_accounts()
if accounts: # So all account(s) belong to the current signed-in user
result = cca.acquire_token_silent(scope, account=accounts[0])
_save_cache(cache)
return result
app.jinja_env.globals.update(_build_auth_code_flow=_build_auth_code_flow) # Used in template
if __name__ == "__main__":
app.run()
Schritt 6: Ausführen ihrer Web-App
Führen Sie die App im Terminal aus, indem Sie den folgenden Befehl eingeben, der den Flask-Entwicklungsserver ausführt. Der Entwicklungsserver sucht standardmäßig nach app.py. Öffnen Sie dann Ihren Browser, und navigieren Sie zur Web-App-URL: http://localhost:5000.
[Optional] Debuggen Ihrer App
Das Debugging-Feature bietet Ihnen die Möglichkeit, ein ausgeführtes Programm in einer bestimmten Codezeile anzuhalten. Wenn Sie das Programm anhalten, können Sie Variablen untersuchen, Code im Bereich "Debugkonsole" ausführen und andernfalls die im Debugging beschriebenen Features nutzen. Informationen zur Verwendung des Visual Studio Code-Debuggers finden Sie in der VS Code-Dokumentation.
Verwenden Sie das Array der args Datei, um den Hostnamen und/oder die launch.json Portnummer zu ändern. Im folgenden Beispiel wird veranschaulicht, wie Sie den Hostnamen für localhost und die Portnummer konfigurieren.5001 Wenn Sie den Hostnamen oder die Portnummer ändern, müssen Sie den Umleitungs-URI oder Ihre Anwendung aktualisieren. Weitere Informationen finden Sie im Schritt "Registrieren einer Webanwendung" .
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Python: Flask",
"type": "python",
"request": "launch",
"module": "flask",
"env": {
"FLASK_APP": "app.py",
"FLASK_ENV": "development"
},
"args": [
"run",
"--host=localhost",
"--port=5001"
],
"jinja": true,
"justMyCode": true
}
]
}
Verwandte Inhalte
- Erfahren Sie, wie Sie die Azure AD B2C-Authentifizierung für Ihre Web-App anpassen und verbessern.