API-Zugriff braucht OAuth-Schutz? Tokens in API Management validieren
Ein API-Schlüssel ist ein gemeinsames Geheimnis. Ein OAuth-Zugriffstoken wird von einem Identitätsanbieter für eine bestimmte API ausgestellt und läuft ab. APIM kann prüfen, ob das Token aus dem erwarteten Mandanten stammt, für diese API bestimmt ist, einen erlaubten Aufrufer identifiziert und die erforderliche Berechtigung enthält.
Dieses Lab verwendet Client Credentials: Eine Anwendung ruft die API unter ihrer eigenen Identität auf, ohne angemeldeten Benutzer. Das eignet sich für Hintergrundaufgaben oder Aufrufe zwischen Diensten. Ein Client Secret authentifiziert den Aufrufer gegenüber Microsoft Entra ID; das erhaltene Zugriffstoken wird an APIM gesendet. Das Client Secret wird nicht an APIM übertragen.
Aufrufer + Client Secret → Entra ID → Zugriffstoken
Aufrufer + Zugriffstoken → APIM prüft Token und Berechtigung → Petstore
Verwende apim-ctgateway-weu → CloudTrips Petstore → v2 im Consumption-Tarif weiter. Schließe den Aufräumschritt des früheren Policy-Labs ab, sodass die Operation nur geerbte Policies verwendet. Dieser Trip schützt nur v2. Original und v1 behalten ihre bisherigen Zugriffsregeln; das öffentliche Petstore-Backend bleibt direkt erreichbar.
Du benötigst Berechtigungen zum Erstellen von Entra-App-Registrierungen und für die Administratorzustimmung zu einer Anwendungsberechtigung deiner eigenen API. Ein geeigneter Entra-Administrator, beispielsweise ein Cloud Application Administrator, kann diese Zustimmung erteilen. Die Rolle Owner eines Azure-Abonnements allein gewährt diese Verzeichnisberechtigungen nicht. Eine neue Hostingressource wird nicht benötigt.
API-Identität registrieren
Öffne im Azure-Portal Microsoft Entra ID → App registrations → New registration:
Name: ct-apim-api
Supported account types: Accounts in this organizational directory only
Redirect URI: leer lassen
Registriere die App. Notiere unter Overview die Application (client) ID als API_APP_ID und die Directory (tenant) ID als TENANT_ID. Verwende die Application ID, nicht die Object ID.
Diese Registrierung repräsentiert deine geschützte Gateway-API. Sie stellt keine API bereit und registriert nicht den öffentlichen Petstore-Dienst in deinem Mandanten.
Öffne Expose an API → Application ID URI → Add / Edit. Speichere den vorgeschlagenen Wert:
api://API_APP_ID
Ersetze API_APP_ID durch die tatsächliche GUID. Für dieses App-zu-App-Lab musst du keinen delegierten Scope hinzufügen.
Öffne Manifest. Suche requestedAccessTokenVersion im vorhandenen api-Objekt und ändere den Wert auf 2. Speichere und erhalte den übrigen Manifestinhalt. Dadurch fordert die API Zugriffstokens im v2-Format an. Die Audience des Tokens ist dann die Application-ID-GUID der API.
Öffne App roles → Create app role:
Display name: Invoke CloudTrips API
Allowed member types: Applications
Value: Api.Invoke
Description: Allows an application to invoke the CloudTrips API.
Do you want to enable this app role?: Yes
Übernimm beziehungsweise speichere. Dies ist eine Anwendungsberechtigung, keine Azure-IAM-Rolle und keine delegierte Benutzerberechtigung.
Aufrufer registrieren und berechtigen
Erstelle eine weitere App-Registrierung im selben Mandanten:
Name: ct-apim-client
Supported account types: Accounts in this organizational directory only
Redirect URI: leer lassen
Notiere ihre Application (client) ID als CLIENT_APP_ID. API und Aufrufer müssen unterschiedliche Application IDs haben.
Öffne in ct-apim-client den Bereich API permissions → Add a permission → My APIs → ct-apim-api → Application permissions. Wähle Api.Invoke → Add permissions. Falls die API nicht unter My APIs erscheint, verwende APIs my organization uses und suche nach API_APP_ID.
Wähle Grant admin consent for your tenant. Prüfe, dass Api.Invoke den Status Granted zeigt. Wenn du diese Zustimmung nicht erteilen kannst, muss der Mandantenadministrator diesen Schritt vor dem Test abschließen.

Öffne in der Aufrufer-App Certificates & secrets → Client secrets → New client secret. Verwende die Beschreibung cloudtrips-lab, wähle eine kurze, zum Lab passende Gültigkeit und füge das Secret hinzu. Kopiere seinen Value, nicht die Secret ID. Bewahre ihn vorübergehend sicher auf; der vollständige Wert wird nur beim Erstellen angezeigt. Nimm ihn nicht in Screenshots auf.
Tokenvalidierung auf v2 durchsetzen
Öffne API Management → apim-ctgateway-weu → APIs → APIs → CloudTrips Petstore → v2 → Design → All operations → Policy-Codeeditor.
Ersetze die Lab-Policy von v2 durch den folgenden Inhalt und ersetze alle drei Platzhalter durch deine tatsächlichen GUIDs:
| Platzhalter | Wert aus |
|---|---|
| TENANT_ID | Directory (tenant) ID |
| API_APP_ID | ct-apim-api → Application (client) ID |
| CLIENT_APP_ID | ct-apim-client → Application (client) ID |
<policies>
<inbound>
<base />
<validate-azure-ad-token tenant-id="TENANT_ID"
header-name="Authorization"
failed-validation-httpcode="401"
failed-validation-error-message="A valid token with Api.Invoke permission is required.">
<client-application-ids>
<application-id>CLIENT_APP_ID</application-id>
</client-application-ids>
<audiences>
<audience>API_APP_ID</audience>
</audiences>
<required-claims>
<claim name="roles" match="any">
<value>Api.Invoke</value>
</claim>
</required-claims>
</validate-azure-ad-token>
<set-header name="Authorization" exists-action="delete" />
<set-header name="Ocp-Apim-Subscription-Key" exists-action="delete" />
<set-query-parameter name="subscription-key" exists-action="delete" />
<set-header name="Accept" exists-action="override">
<value>application/json</value>
</set-header>
</inbound>
<backend>
<base />
</backend>
<outbound>
<base />
<set-header name="X-CloudTrips-API-Version" exists-action="override">
<value>v2</value>
</set-header>
</outbound>
<on-error>
<base />
</on-error>
</policies>
Speichere. Die Validierung prüft Signatur, Ablaufzeit, Mandant, Audience, Aufrufer und die Rolle Api.Invoke. Verwende für das oben konfigurierte Token im v2-Format die reine API_APP_ID-GUID als Audience, nicht api://... und nicht die Gateway-URL.
Nach der Validierung entfernt die Policy Authorization vor der Weiterleitung an das öffentliche Petstore-Backend. Das Token ist für unsere Gateway-API bestimmt; Petstore benötigt es nicht. Ein echtes privates Backend bräuchte einen eigenen geeigneten Zugriffsschutz.
Öffne jetzt v2 → Settings, setze Subscription required auf Off und speichere. Erledige dies nach dem Speichern der Tokenvalidierung. Für diese Version ist OAuth die Zugriffskontrolle; der Client benötigt nicht zusätzlich einen APIM-Subscription-Schlüssel. Original und v1 können ihre Schlüsselpflicht behalten.

Die APIM-Seite OAuth 2.0 authorization servers musst du für diesen Test nicht konfigurieren. Diese Konfiguration hilft Testkonsolen beim Beschaffen von Tokens; sie ersetzt die Validierungspolicy am Gateway nicht.
Drei Zugriffstests ausführen
Lade apim-oauth-demo.py herunter. Öffne Azure Cloud Shell → Bash, lade die Datei über Manage files → Upload hoch und führe aus:
python3 apim-oauth-demo.py
Das Skript benötigt weder zusätzliche Pakete noch az login. Gib an den Eingabeaufforderungen ein:
- TENANT_ID.
- API_APP_ID von ct-apim-api.
- CLIENT_APP_ID von ct-apim-client.
- Deinen APIM-Ressourcennamen, beispielsweise apim-ctgateway-weu.
- Den Value des Client Secrets des Aufrufers, sobald danach gefragt wird. Die Eingabe bleibt verborgen.
Das Skript ruft /petstore/v2/pet/findByStatus?status=available ohne Token, mit ungültigem Token und anschließend mit einem echten Token auf. Es fordert dieses Token bei deinem Mandanten mit dem Client-Credentials-Grant und dem Scope api://API_APP_ID/.default an. .default fordert hier die dem Aufrufer bereits erteilten Anwendungsberechtigungen der API an; dadurch werden keine neuen Berechtigungen erteilt.
Erwartete Ausgabe:
NO TOKEN: HTTP 401
INVALID TOKEN: HTTP 401
Requesting an access token from Microsoft Entra ID...
VALID TOKEN: HTTP 200
API version: v2
Pet records returned: ... (shared demo data varies)
PASS: missing and invalid tokens rejected; authorized call succeeded.
Das Skript zeigt Token und Client Secret nicht an und speichert sie nicht. Die Datensatzanzahl kann variieren und auch null sein. Fehlende oder ungültige Tokens sollten vor dem Backend abgewiesen werden; der autorisierte Aufruf sollte Petstore-Daten über APIM erhalten.

Falls der Zugriff weiterhin fehlschlägt
- Tokenanforderung schlägt fehl: Prüfe Mandanten- und Aufrufer-ID, Value und Gültigkeit des Client Secrets, die Application ID URI der API und die Administratorzustimmung. Gib Konfigurationsänderungen Zeit zur Verteilung und starte erneut.
- Gültiges Token erhält 401: Prüfe die drei GUIDs in der Policy, die Schreibweise Api.Invoke und
requestedAccessTokenVersion: 2in der API-Registrierung. Stelle sicher, dass Subscription required auf v2 ausgeschaltet ist. Starte nach Korrekturen erneut, um ein frisches Token zu erhalten. - 400 oder 429: Entferne die Regeln auf Operationsebene aus dem früheren Policy-Lab in v2. Behalte
<base />in jedem Abschnitt bei, damit die OAuth-Policy auf API-Ebene geerbt wird. - Ohne Token kommt 200: Stoppe und prüfe die konkrete v2-Policy sowie die URL. Die Route ist nicht wie vorgesehen geschützt.
- 5xx: Prüfe die Verfügbarkeit des öffentlichen Backends. Ein Backendfehler beweist keinen Fehler bei der Tokenvalidierung.
Abschluss
Behalte die Validierungspolicy bei, wenn du diesen geschützten v2-Endpunkt weiter nutzt. Bevor du sie entfernst, aktiviere Subscription required wieder, damit v2 nach dem Entfernen von OAuth nicht anonym zugänglich wird.
Lösche nach Abschluss ct-apim-client und ct-apim-api unter Entra ID → App registrations und entferne sicher aufbewahrte Kopien des Lab-Secrets. Diese Registrierungen sind Verzeichnisobjekte; das Löschen der Azure-Ressourcengruppe entfernt sie nicht. Wenn du auch mit APIM fertig bist, lösche rg-cloudtrips-apim-test-weu.