Freigeben über


Erstellen einer REST-API für ein Tokenausstellungs-Startereignis in Azure Functions

In diesem Artikel wird beschrieben, wie Sie eine REST-API mit einem Startereignis zur Tokenausstellung mithilfe von Azure Functions im Azure-Portal erstellen. Sie erstellen eine Azure Function-App und eine HTTP-Triggerfunktion, die zusätzliche Ansprüche für Ihr Token zurückgeben kann.

Voraussetzungen

In diesem Artikel wird beschrieben, wie Sie eine REST-API für ein Startereignis zur Tokenausstellung mithilfe der NuGet-Bibliothek Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents erstellen und sie für die Authentifizierung einrichten. Sie erstellen eine HTTP-Triggerfunktion in Visual Studio oder Visual Studio Code, konfigurieren sie für die Authentifizierung und stellen sie im Azure-Portal bereit, wo auf sie über Azure Functions zugegriffen werden kann.

Voraussetzungen

Hinweis

Die NuGet-Bibliothek Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents befindet sich derzeit in der Vorschau. Die Schritte in diesem Artikel können sich ändern. Eine Implementierung der allgemeinen Verfügbarkeit eines Startereignisses für die Tokenausstellungen können Sie über das Azure-Portal implementieren.

Erstellen der Azure Function-App

Erstellen Sie im Azure-Portal eine Azure Function-App und die zugehörige Ressource, bevor Sie die HTTP-Triggerfunktion erstellen.

  1. Melden Sie sich beim Azure-Portal mindestens mit der Rolle Anwendungsadministrator und Authentifizierungsadministrator an.

  2. Klicken Sie im Menü des Azure-Portals oder auf der Startseite auf Ressource erstellen.

  3. Suchen Sie nach Funktions-App, und wählen Sie diese Option und dann Erstellen aus.

  4. Erstellen Sie auf der Seite Grundlagen eine Funktions-App mit den Einstellungen, die in der folgenden Tabelle angegeben sind:

    Einstellung Vorgeschlagener Wert BESCHREIBUNG
    Abonnement Ihr Abonnement Das Abonnement, unter dem die neue Funktions-App erstellt wird.
    Ressourcengruppe myResourceGroup Wählen Sie eine vorhandene Ressourcengruppe oder einen Namen für die neue Ressourcengruppe aus, in der Ihre Funktions-App erstellt werden soll.
    Name der Funktions-App Global eindeutiger Name Ein Name, der die neue Funktions-App identifiziert. Gültige Zeichen sind a-z (Groß-/Kleinschreibung nicht beachtet), 0-9 und -.
    Bereitstellen von Code oder eines Containerimages Code Option zum Veröffentlichen von Codedateien oder eines Docker-Containers. In diesem Tutorial wählen Sie Code aus.
    Laufzeitstapel .NET Ihre bevorzugte Programmiersprache. In diesem Tutorial wählen Sie .NET aus.
    Version 6 (LTS) In-Process Die Version der .NET-Runtime. In-Process bedeutet, dass Sie Funktionen im Portal erstellen und ändern können. Dies wird für diesen Leitfaden empfohlen.
    Region Bevorzugte Region Wählen Sie eine Region in Ihrer Nähe oder in der Nähe anderer Dienste aus, auf die Ihre Funktionen zugreifen können.
    Betriebssystem Windows Das Betriebssystem wird für Sie basierend auf der Auswahl des Runtimestapels vorab ausgewählt.
    Plantyp Verbrauchstarif (Serverloses Computing) Der Hostingplan, der definiert, wie Ihre Ressourcen der Funktionen-App zugewiesen werden
  5. Wählen Sie Überprüfen und erstellen aus, um die ausgewählte App-Konfiguration zu überprüfen, und wählen Sie dann Erstellen aus. Die Bereitstellung nimmt einige Minuten in Anspruch.

  6. Wählen Sie nach der Bereitstellung Zu Ressource wechseln aus, um Ihre neue Funktions-App anzuzeigen.

Erstellen einer HTTP-Triggerfunktion

Nachdem die Azure-Funktions-App erstellt wurde, können Sie eine HTTP-Triggerfunktion innerhalb der App erstellen. Mit dem HTTP-Trigger können Sie eine Funktion mit einer HTTP-Anforderung aufrufen und von Ihrer benutzerdefinierten Microsoft Entra-Authentifizierungserweiterung referenzieren lassen.

  1. Wählen Sie auf der Seite Übersicht Ihrer Funktions-App den Bereich Funktionen aus, und wählen Sie unter Im Azure-Portal erstellen die Option Funktion erstellen aus.
  2. Übernehmen Sie im Fenster Funktion erstellen für die Eigenschaft Entwicklungsumgebung die Option Im Portal entwickeln. Wählen Sie unter Vorlage die Option HTTP-Trigger aus.
  3. Geben Sie unter Vorlagendetails für die Eigenschaft Neue Funktion die Zeichenfolge CustomAuthenticationExtensionsAPI ein.
  4. Wählen Sie für die Autorisierungsstufe die Option Funktion aus.
  5. Klicken Sie auf Erstellen. Screenshot: Auswählen der Entwicklungsumgebung und der Vorlage.

Bearbeiten Sie die -Funktion

Der Code liest das eingehende JSON-Objekt und Microsoft Entra ID sendet das JSON-Objekt an Ihre API. In diesem Beispiel wird der Wert der Korrelations-ID gelesen. Anschließend gibt der Code eine Auflistung von angepassten Ansprüchen zurück, einschließlich der ursprünglichen Korrelations-ID (CorrelationId), der API-Version (ApiVersion) Ihrer Azure-Funktion, des Geburtsdatums (DateOfBirth) und der benutzerdefinierten Rollen (CustomRoles), die an Microsoft Entra ID zurückgegeben wird.

  1. Wählen Sie Menü unter Entwickler die Option Programmieren und testen aus.

  2. Ersetzen Sie den gesamten Code durch den folgenden Codeschnipsel, und wählen Sie dann Speichern aus.

    #r "Newtonsoft.Json"
    using System.Net;
    using Microsoft.AspNetCore.Mvc;
    using Microsoft.Extensions.Primitives;
    using Newtonsoft.Json;
    public static async Task<IActionResult> Run(HttpRequest req, ILogger log)
    {
        log.LogInformation("C# HTTP trigger function processed a request.");
        string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
        dynamic data = JsonConvert.DeserializeObject(requestBody);
    
        // Read the correlation ID from the Microsoft Entra request    
        string correlationId = data?.data.authenticationContext.correlationId;
    
        // Claims to return to Microsoft Entra
        ResponseContent r = new ResponseContent();
        r.data.actions[0].claims.CorrelationId = correlationId;
        r.data.actions[0].claims.ApiVersion = "1.0.0";
        r.data.actions[0].claims.DateOfBirth = "01/01/2000";
        r.data.actions[0].claims.CustomRoles.Add("Writer");
        r.data.actions[0].claims.CustomRoles.Add("Editor");
        return new OkObjectResult(r);
    }
    public class ResponseContent{
        [JsonProperty("data")]
        public Data data { get; set; }
        public ResponseContent()
        {
            data = new Data();
        }
    }
    public class Data{
        [JsonProperty("@odata.type")]
        public string odatatype { get; set; }
        public List<Action> actions { get; set; }
        public Data()
        {
            odatatype = "microsoft.graph.onTokenIssuanceStartResponseData";
            actions = new List<Action>();
            actions.Add(new Action());
        }
    }
    public class Action{
        [JsonProperty("@odata.type")]
        public string odatatype { get; set; }
        public Claims claims { get; set; }
        public Action()
        {
            odatatype = "microsoft.graph.tokenIssuanceStart.provideClaimsForToken";
            claims = new Claims();
        }
    }
    public class Claims{
        [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
        public string CorrelationId { get; set; }
        [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
        public string DateOfBirth { get; set; }
        public string ApiVersion { get; set; }
        public List<string> CustomRoles { get; set; }
        public Claims()
        {
            CustomRoles = new List<string>();
        }
    }
    
  3. Wählen Sie im oberen Menü die Option Funktions-URL abrufen aus, und kopieren Sie den Wert der URL. Diese Funktions-URL kann beim Einrichten einer benutzerdefinierten Authentifizierungserweiterung verwendet werden.

Erstellen und Kompilieren der Azure Function-App

In diesem Schritt erstellen Sie eine HTTP-Triggerfunktions-API mit Ihrer IDE, installieren die erforderlichen NuGet-Pakete und kopieren sie in den Beispielcode. Sie erstellen das Projekt und führen die Funktion lokal aus, um die lokale Funktions-URL zu extrahieren.

Erstellen der Anwendung

Führen Sie die folgenden Schritte aus, um eine Azure Function-App zu erstellen:

  1. Öffnen Sie Visual Studio, und wählen Sie Neues Projekt erstellen aus.
  2. Suchen und wählen Sie Azure Functions aus und wählen Sie dann Weiter aus.
  3. Geben Sie dem Projekt einen Namen, z. B. AuthEventsTrigger. Es ist ratsam, den Projektmappennamen an den Projektnamen anzugleichen.
  4. Wählen Sie einen Speicherort für das Projekt aus. Wählen Sie Weiter aus.
  5. Wählen Sie .NET 6.0 (Long Term Support) als Zielframework aus.
  6. Wählen Sie HTTP-Trigger als Funktionstyp aus und legen Sie Autorisierungsstufe auf Funktion festgelegt ist. Klicken Sie auf Erstellen.
  7. Benennen Sie im Projektmappen-Explorer die Datei Function1.cs in AuthEventsTrigger.cs um, und übernehmen Sie den Änderungsvorschlag für die Umbenennung.

Installieren von NuGet-Paketen und Erstellen des Projekts

Nach dem Erstellen des Projekts müssen Sie die erforderlichen NuGet-Pakete installieren und das Projekt kompilieren.

  1. Wählen Sie im oberen Menü von Visual Studio Projekt und NuGet-Pakete verwalten aus.
  2. Wählen Sie die Registerkarte Durchsuchen aus, und wählen Sie dann im rechten Bereich Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents aus. Wählen Sie Installieren aus.
  3. Übernehmen und akzeptieren Sie die Änderungen in den angezeigten Popups.

Hinzufügen des Beispielcodes

Die Funktions-API ist die Quelle zusätzlicher Ansprüche für Ihr Token. Im Rahmen dieses Artikels werden die Werte für die Beispiel-App hartcodiert. In der Produktion können Sie aus dem externen Datenspeicher Informationen über den Benutzer oder die Benutzerin abrufen.

Ersetzen Sie den gesamten Inhalt der Datei AuthEventsTrigger.cs durch den folgenden Code:

using System;
using Microsoft.Azure.WebJobs;
using Microsoft.Extensions.Logging;
using Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents.TokenIssuanceStart;
using Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents;

namespace AuthEventsTrigger
{
    public static class AuthEventsTrigger
    {
        [FunctionName("onTokenIssuanceStart")]
        public static WebJobsAuthenticationEventResponse Run(
            [WebJobsAuthenticationEventsTrigger] WebJobsTokenIssuanceStartRequest request, ILogger log)
        {
            try
            {
                // Checks if the request is successful and did the token validation pass
                if (request.RequestStatus == WebJobsAuthenticationEventsRequestStatusType.Successful)
                {
                    // Fetches information about the user from external data store
                    // Add new claims to the token's response
                    request.Response.Actions.Add(
                        new WebJobsProvideClaimsForToken(
                            new WebJobsAuthenticationEventsTokenClaim("dateOfBirth", "01/01/2000"),
                            new WebJobsAuthenticationEventsTokenClaim("customRoles", "Writer", "Editor"),
                            new WebJobsAuthenticationEventsTokenClaim("apiVersion", "1.0.0"),
                            new WebJobsAuthenticationEventsTokenClaim(
                                "correlationId", 
                                request.Data.AuthenticationContext.CorrelationId.ToString())));
                }
                else
                {
                    // If the request fails, such as in token validation, output the failed request status, 
                    // such as in token validation or response validation.
                    log.LogInformation(request.StatusMessage);
                }
                return request.Completed();
            }
            catch (Exception ex) 
            { 
                return request.Failed(ex);
            }
        }
    }
}

Lokales Erstellen und Ausführen des Projekts

Das Projekt wurde erstellt, und der Beispielcode wurde hinzugefügt. Wir müssen das Projekt mit Ihrer IDE lokal erstellen und ausführen, um die lokale Funktions-URL zu extrahieren.

  1. Navigieren Sie im oberen Menü zu Erstellen und wählen Sie Projektmappe erstellen aus.
  2. Drücken Sie F5 oder wählen Sie AuthEventsTrigger aus dem oberen Menü aus, um die Funktion auszuführen.
  3. Kopieren Sie die Funktions-URL aus dem Terminal, das beim Ausführen der Funktion erscheint. Dies kann beim Einrichten einer benutzerdefinierten Authentifizierungserweiterung verwendet werden.

Es ist ratsam, die Funktion lokal zu testen, bevor Sie diese in Azure bereitstellen. Wir können einen JSON-Dummytext verwenden, der die Anforderung imitiert, die Microsoft Entra ID an Ihre REST-API sendet. Verwenden Sie Ihr bevorzugtes API-Testtool, um die Funktion direkt aufzurufen.

  1. Öffnen Sie die Datei local.settings.json in Ihrer IDE, und ersetzen Sie den Code durch den folgenden JSON-Code. Zu lokalen Testzwecken kann "AuthenticationEvents__BypassTokenValidation" auf true festgelegt werden.

    {
      "IsEncrypted": false,
      "Values": {
        "AzureWebJobsStorage": "",
        "AzureWebJobsSecretStorageType": "files",
        "FUNCTIONS_WORKER_RUNTIME": "dotnet",
        "AuthenticationEvents__BypassTokenValidation" : true
      }
    }
    
  2. Erstellen Sie mithilfe Ihres bevorzugten API-Testtools eine neue HTTP-Anforderung, und legen Sie die HTTP-Methode auf POST fest.

  3. Fügen Sie den folgenden JSON-Text ein, der die Anforderung imitiert, die Microsoft Entra ID an Ihre REST-API sendet.

    {
        "type": "microsoft.graph.authenticationEvent.tokenIssuanceStart",
        "source": "/tenants/aaaabbbb-0000-cccc-1111-dddd2222eeee/applications/00001111-aaaa-2222-bbbb-3333cccc4444",
        "data": {
            "@odata.type": "microsoft.graph.onTokenIssuanceStartCalloutData",
            "tenantId": "aaaabbbb-0000-cccc-1111-dddd2222eeee",
            "authenticationEventListenerId": "11112222-bbbb-3333-cccc-4444dddd5555",
            "customAuthenticationExtensionId": "22223333-cccc-4444-dddd-5555eeee6666",
            "authenticationContext": {
                "correlationId": "aaaa0000-bb11-2222-33cc-444444dddddd",
                "client": {
                    "ip": "127.0.0.1",
                    "locale": "en-us",
                    "market": "en-us"
                },
                "protocol": "OAUTH2.0",
                "clientServicePrincipal": {
                    "id": "aaaaaaaa-0000-1111-2222-bbbbbbbbbbbb",
                    "appId": "00001111-aaaa-2222-bbbb-3333cccc4444",
                    "appDisplayName": "My Test application",
                    "displayName": "My Test application"
                },
                "resourceServicePrincipal": {
                    "id": "aaaaaaaa-0000-1111-2222-bbbbbbbbbbbb",
                    "appId": "00001111-aaaa-2222-bbbb-3333cccc4444",
                    "appDisplayName": "My Test application",
                    "displayName": "My Test application"
                },
                "user": {
                    "companyName": "Casey Jensen",
                    "createdDateTime": "2023-08-16T00:00:00Z",
                    "displayName": "Casey Jensen",
                    "givenName": "Casey",
                    "id": "00aa00aa-bb11-cc22-dd33-44ee44ee44ee",
                    "mail": "casey@contoso.com",
                    "onPremisesSamAccountName": "Casey Jensen",
                    "onPremisesSecurityIdentifier": "<Enter Security Identifier>",
                    "onPremisesUserPrincipalName": "Casey Jensen",
                    "preferredLanguage": "en-us",
                    "surname": "Jensen",
                    "userPrincipalName": "casey@contoso.com",
                    "userType": "Member"
                }
            }
        }
    }
    
    
  4. Nach dem Klicken auf Senden sollten Sie eine JSON-Antwort erhalten, die in etwa Folgendem entspricht:

    {
        "data": {
            "@odata.type": "microsoft.graph.onTokenIssuanceStartResponseData",
            "actions": [
                {
                    "@odata.type": "microsoft.graph.tokenIssuanceStart.provideClaimsForToken",
                    "claims": {
                        "customClaim1": "customClaimValue1",
                        "customClaim2": [
                            "customClaimString1",
                            "customClaimString2" 
                        ]
                    }
                }
    
            ]
        }
    }
    

Bereitstellen der Funktion und Veröffentlichen in Azure

Die Funktion muss mithilfe unserer IDE in Azure bereitgestellt werden. Überprüfen Sie, ob Sie ordnungsgemäß bei Ihrem Azure-Konto angemeldet sind, damit die Funktion veröffentlicht werden kann.

  1. Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf das Projekt, und wählen Sie veröffentlichen aus.

  2. Wählen Sie in Ziel, Azure und dann Weiter aus.

  3. Wählen Sie Azure Function-App (Windows) für das Spezifische Ziel, dannAzure Function App (Windows) und zuletzt Weiter aus.

  4. Verwenden Sie in der Funktionsinstanz die Dropdownliste Abonnementnamen, um das Abonnement auszuwählen, unter dem die neue Funktions-App erstellt wird.

  5. Wählen Sie aus, wo die neue Funktions-App veröffentlicht werden soll, und wählen Sie Neue erstellen aus.

  6. Verwenden Sie auf der Seite Funktions-App (Windows) die Einstellungen der Funktions-App, wie in der folgenden Tabelle angegeben, und wählen Sie dann Erstellen aus.

    Einstellung Vorgeschlagener Wert Beschreibung
    Name Global eindeutiger Name Ein Name, der die neue Funktions-App identifiziert. Gültige Zeichen sind a-z (Groß-/Kleinschreibung nicht beachtet), 0-9 und -.
    Abonnement Ihr Abonnement Das Abonnement, unter dem die neue Funktions-App erstellt wird.
    Ressourcengruppe myResourceGroup Wählen Sie eine vorhandene Ressourcengruppe aus oder benennen Sie eine neue, in der Sie Ihre Funktions-App erstellen.
    Plantyp Verbrauchstarif (Serverloses Computing) Der Hostingplan, der definiert, wie Ihre Ressourcen der Funktionen-App zugewiesen werden
    Location Bevorzugte Region Wählen Sie eine Region in Ihrer Nähe oder in der Nähe anderer Dienste aus, auf die Ihre Funktionen zugreifen können.
    Azure Storage (in englischer Sprache) Ihr Speicherkonto Für die Functions-Laufzeit ist ein Azure-Speicherkonto erforderlich. Wählen Sie Neu aus, um ein universelles Speicherkonto zu konfigurieren.
    Application Insights Standard Ein Feature von Azure Monitor. Diese ist automatisch ausgewählt. Wählen Sie die Option aus, die Sie verwenden oder konfigurieren möchten.
  7. Warten Sie einige Augenblicke, bis Ihre Funktions-App bereitgestellt wird. Nachdem das Fenster geschlossen wurde, wählen Sie Fertig stellen aus.

  8. Ein neuer Veröffentlichungsbereich wird geöffnet. Wählen Sie oben Veröffentlichen aus. Warten Sie einige Minuten, bis Ihre Funktions-App bereitgestellt und im Azure-Portal angezeigt wird.

Konfigurieren der Authentifizierung für Ihre Azure-Funktion

Es gibt drei Möglichkeiten, die Authentifizierung für Ihre Azure-Funktion einzurichten:

Standardmäßig wurde der Code im Azure-Portal mithilfe von Umgebungsvariablen für die Authentifizierung eingerichtet. Verwenden Sie die Registerkarten unten, um Ihre bevorzugte Methode für die Implementierung von Umgebungsvariablen auszuwählen, oder verweisen Sie alternativ auf die integrierte Azure App-Dienstauthentifizierung und Autorisierung. Verwenden Sie die folgenden Werte zum Einrichten von Umgebungsvariablen:

Name Wert
AuthenticationEvents__AudienceAppId App-ID der benutzerdefinierten Authentifizierungserweiterung, die unter Konfigurieren eines benutzerdefinierten Anspruchsanbieters für ein Tokenausstellungsereignis eingerichtet wird
AuthenticationEvents__AuthorityUrl • Mitarbeitermandant https://login.microsoftonline.com/<tenantID>
• Externer Mandant https://<mydomain>.ciamlogin.com
AuthenticationEvents__AuthorizedPartyAppId 99045fe1-7639-4a75-9d4a-577b6ca3810f oder eine andere autorisierte Partei

Einrichten der Authentifizierung im Azure-Portal mit Umgebungsvariablen

  1. Melden Sie sich beim Azure-Portal als Anwendungsadministrator oder Authentifizierungsadministrator an.
  2. Navigieren Sie zu der von Ihnen erstellten Funktions-App und wählen Sie unter Einstellungen die Option Konfiguration aus.
  3. Wählen Sie unter Anwendungseinstellungen die Option Neue Anwendungseinstellung aus, und fügen Sie die folgenden Umgebungsvariablen aus der Tabelle und die zugehörigen Werte hinzu.
  4. Wählen Sie Speichern, um die Anwendungseinstellungen zu speichern.

Nächster Schritt