Web-App braucht Benutzer-Login? Authorization Code Flow verwenden

Veröffentlicht am:

In Enterprise-Systemen muessen Webanwendungen haeufig Benutzer anmelden und APIs in deren Namen aufrufen.

Dieses Muster wird verwendet, wenn:

  • ein Benutzer vorhanden ist
  • die Anwendung auf einem vertrauenswuerdigen Server laeuft
  • die Authentifizierung ueber Microsoft Entra ID erfolgt
  • die App delegierten Zugriff auf eine API benoetigt

In diesem Beispiel:

  • CloudTrips Web App ist die Client-Anwendung
  • CloudTrips API ist die Resource-Anwendung
  • Employee ist der angemeldete Benutzer

Die Authentifizierung erfolgt mit dem OAuth 2.0 Authorization Code Flow. Die Autorisierung wird ueber delegierte Berechtigungen gesteuert.

Architektur

Employee -> CloudTrips Web App -> Microsoft Entra ID -> CloudTrips API

Der Browser meldet den Benutzer ueber Microsoft Entra ID an.

Die Web-App erhaelt einen Authorization Code.

Die Web-App tauscht diesen Code serverseitig gegen Tokens aus.

Demo-Apps

Dieser Trip kann mit den lokalen Beispiel-Apps demonstriert werden:

examples/auth-code-flow

Die Demo enthaelt:

  • CloudTrips-Web auf http://localhost:5001
  • CloudTrips-API auf http://localhost:5002

Verwende fuer die Demo diese Redirect URI:

http://localhost:5001/signin-oidc

In Produktion verwendest du HTTPS und die echte Anwendungs-URL.

CloudTrips API App erstellen

Erstelle zuerst die Resource-Anwendung.

Gehe zu:

Entra ID > App registrations > New registration

Erstelle eine Anwendung:

Name: CloudTrips-API

Diese App Registration repraesentiert die API, die Access Tokens empfaengt und validiert.

Microsoft Entra App-Registrierung mit CloudTrips API als Anwendungsname

API exponieren

Oeffne in CloudTrips-API:

Expose an API

Setze die Application ID URI:

api://<cloudtrips-api-application-id>

Dieser Bezeichner wird zur Audience fuer Access Tokens, die fuer die CloudTrips API ausgestellt werden.

CloudTrips API App Registration auf der Expose an API Seite mit konfigurierter Application ID URI

Delegierten Scope erstellen

Fuege in CloudTrips-API einen Scope hinzu:

Expose an API > Add a scope

Beispiel:

Scope name: Trips.Read
Who can consent: Admins and users
Admin consent display name: Read CloudTrips trips
User consent display name: Read your CloudTrips trips
State: Enabled

Damit definierst du benutzerdelegierte Autorisierung.

Die CloudTrips API kann spaeter pruefen, ob das eingehende Token den benoetigten Scope enthaelt.

Add a scope Formular fuer CloudTrips API mit Trips.Read und Consent-Einstellungen

CloudTrips Web App erstellen

Erstelle jetzt die Client-Anwendung.

Gehe zu:

Entra ID > App registrations > New registration

Erstelle eine Anwendung:

Name: CloudTrips-Web
Supported account types: Single tenant
Redirect URI platform: Web
Redirect URI: http://localhost:5001/signin-oidc

Die Redirect URI ist die Adresse, an die Microsoft Entra ID den Browser nach der Anmeldung zuruecksendet.

In Produktion verwendest du statt localhost die echte Anwendungs-URL.

Microsoft Entra App-Registrierung mit CloudTrips Web und Web Redirect URI

Client Secret erstellen

Erstelle in CloudTrips-Web ein Client Secret:

Certificates & secrets > New client secret

Speichere den Secret-Wert sicher.

Die Web-App verwendet dieses Secret, wenn sie den Authorization Code gegen Tokens austauscht.

In echten Projekten sind zertifikatsbasierte Credentials fuer produktive Web-Apps oft die bessere Wahl. Wenn ein Client Secret verwendet wird, rotiere es regelmaessig und speichere es nie im Source Code.

CloudTrips Web Certificates and secrets Seite mit erstelltem Client Secret

API-Berechtigung hinzufuegen

Gehe zu:

App registrations > CloudTrips-Web > API permissions

Waehle:

Add a permission

Waehle:

My APIs > CloudTrips-API > Delegated permissions > Trips.Read

Damit darf die CloudTrips Web App ein Access Token fuer die CloudTrips API im Namen des angemeldeten Benutzers anfordern.

CloudTrips Web API permissions Seite mit ausgewaehlter delegierter CloudTrips API Berechtigung Trips.Read

Wenn dein Tenant Administratorfreigabe verlangt, klicke:

Grant admin consent

CloudTrips Web API permissions Seite nach erteiltem Admin Consent

Authorization Code Flow zur Laufzeit

Zur Laufzeit wird der Browser zu Microsoft Entra ID weitergeleitet:

GET https://login.microsoftonline.com/<tenant-id>/oauth2/v2.0/authorize

Request-Parameter:

client_id=CLOUDTRIPS_WEB_CLIENT_ID
response_type=code
redirect_uri=http://localhost:5001/signin-oidc
response_mode=form_post
scope=openid profile offline_access api://<cloudtrips-api-application-id>/Trips.Read
state=<random-state-value>

Der Benutzer meldet sich an und durchlaeuft bei Bedarf Conditional Access oder MFA.

Microsoft Entra Anmeldeseite fuer das Benutzerkonto

Microsoft Entra ID leitet den Browser danach zurueck an:

http://localhost:5001/signin-oidc

Die Antwort enthaelt einen Authorization Code.

Browser Developer Tools mit signin-oidc Callback und Authorization Code

Code gegen Tokens austauschen

Die Web-App sendet den Authorization Code serverseitig an Microsoft Entra ID:

POST https://login.microsoftonline.com/<tenant-id>/oauth2/v2.0/token

Request Body:

client_id=CLOUDTRIPS_WEB_CLIENT_ID
client_secret=SECRET
grant_type=authorization_code
code=AUTHORIZATION_CODE
redirect_uri=http://localhost:5001/signin-oidc
scope=openid profile offline_access api://<cloudtrips-api-application-id>/Trips.Read

Das Client Secret wird nur vom Server gesendet.

Es darf niemals in Browser-JavaScript sichtbar sein.

Application Log mit Authorization Code Token Request an Microsoft Entra

Token-Ergebnis

Die Token-Antwort enthaelt normalerweise:

  • ID Token fuer den angemeldeten Benutzer
  • Access Token fuer die CloudTrips API
  • Refresh Token, wenn offline_access angefordert und erlaubt wurde

Das ID Token beweist, wer sich bei der Web-App angemeldet hat.

Das Access Token wird an die CloudTrips API gesendet.

Application Log mit erfolgreicher Token-Antwort inklusive ID Token und Access Token

Access Token Claims

Das Access Token enthaelt:

  • Audience: CloudTrips API
  • Scope: Trips.Read
  • Benutzeridentitaet
  • Tenant ID
  • Token Issuer

Wichtige Claims:

Claim Bedeutung
aud API, die das Token akzeptieren soll
scp Delegierte Berechtigungen, die der Client-App erteilt wurden
sub Stabiler Benutzerbezeichner fuer diese App
tid Tenant ID
iss Token Issuer

Decodiertes Access Token mit Audience, delegiertem Scope, Tenant, Subject und Issuer Claims

Die CloudTrips API sollte das Token validieren, bevor sie den Request akzeptiert.

Mindestens validieren:

  • Signatur
  • Issuer
  • Audience
  • Ablaufzeit
  • erforderlicher Scope

Delegierter Zugriff

Authorization Code Flow erstellt ein delegiertes Token.

Das bedeutet:

  • ein Benutzer hat sich angemeldet
  • die Web-App handelt im Namen dieses Benutzers
  • die API erhaelt Benutzerkontext
  • Berechtigungen erscheinen im scp Claim

Das unterscheidet sich vom Client Credentials Flow.

Client Credentials Flow erstellt ein Application Token ohne Benutzeridentitaet.

Extra: App Role ueber Gruppe hinzufuegen

Scopes beantworten diese Frage:

Was darf die Client-App im Namen des Benutzers tun?

App Roles beantworten eine andere Frage:

Welche Rolle hat dieser angemeldete Benutzer innerhalb der Anwendung?

Zum Beispiel kann CloudTrips eine Anwendungsrolle benoetigen:

Trips.Approver

Diese Rolle kann einer Microsoft Entra Gruppe zugewiesen werden. Wenn sich ein Benutzer aus dieser Gruppe anmeldet und ein Token fuer die CloudTrips API erhaelt, kann das Access Token einen roles Claim enthalten.

Benutzer-App-Role erstellen

Oeffne in CloudTrips-API:

App roles > Create app role

Beispiel:

Display name: Trips Approver
Allowed member types: Users/Groups
Value: Trips.Approver
Description: Can approve CloudTrips travel requests
Do you want to enable this app role: Yes

Diese Rolle gehoert zur Resource-Anwendung, weil die CloudTrips API die Rolle liest und durchsetzt.

CloudTrips API App roles Seite mit Trips Approver und dem Wert Trips.Approver

Gruppe der App Role zuweisen

Oeffne die Enterprise Application der API:

Entra ID > Enterprise applications > CloudTrips-API

Gehe dann zu:

Users and groups > Add user/group

Waehle eine Gruppe:

GRP-CloudTrips-Approvers

Waehle die Rolle:

Trips Approver

Jetzt erhaelt jeder Benutzer in dieser Gruppe die Anwendungsrolle, wenn ein Token fuer die CloudTrips API ausgestellt wird.

Der Benutzer muss sich eventuell abmelden und neu anmelden, bevor die neue Rolle im Token erscheint.

CloudTrips API Enterprise Application Users and groups Seite mit Approvers-Gruppe in der Trips Approver Rolle

Ergebnis im Role Claim

Melde den Benutzer erneut an und decodiere danach das Access Token.

Das Token kann nun beides enthalten:

{
  "scp": "Trips.Read",
  "roles": [
    "Trips.Approver"
  ]
}

Decodiertes Access Token mit Trips.Read Scope und Trips.Approver Rolle

Die CloudTrips API kann dann beide Werte pruefen:

  • scp bestaetigt die delegierte Berechtigung zum Aufruf der API
  • roles bestaetigt die Anwendungsrolle des Benutzers

Beispiel:

Lesen von Reisen erlauben, wenn scp Trips.Read enthaelt
Genehmigen von Reisen erlauben, wenn roles Trips.Approver enthaelt

Das ist meist sauberer, als rohe Gruppen-IDs in der API zu pruefen. Gruppen-IDs sind tenant-spezifisch, schwerer zu lesen, und grosse Gruppenmitgliedschaften koennen zu Token Overage fuehren.

Enterprise-Hinweis

Echte Enterprise-Umgebungen haben normalerweise mehrere Stages:

  • DEV
  • TEST oder STAGE
  • PROD

Wenn diese Umgebungen verschiedene Anwendungs-URLs oder verschiedene API-Deployments verwenden, erstelle separate App Registrations pro Umgebung.

Beispiel:

CloudTrips-Web-DEV
CloudTrips-Web-TEST
CloudTrips-Web-PROD

CloudTrips-API-DEV
CloudTrips-API-TEST
CloudTrips-API-PROD

Das bietet:

  • isolierte Redirect URIs
  • getrennte Client Credentials
  • sicherere Consent-Grenzen fuer Produktion
  • klarere Token Audiences
  • saubereres Auditing und Troubleshooting

Vergleich

Flow Benutzer vorhanden Token-Typ Typischer Einsatz
Authorization Code Ja Delegated Serverseitige Web-App
Client Credentials Nein Application Hintergrund-Systemintegration
Managed Identity Nein Application Azure-gehosteter Workload