Tworzenie interfejsu API REST dla zdarzenia rozpoczęcia wystawiania tokenu w usłudze Azure Functions

W tym artykule opisano sposób tworzenia interfejsu API REST z zdarzeniem rozpoczęcia wystawiania tokenu przy użyciu usługi Azure Functions w witrynie Azure Portal. Tworzysz aplikację funkcji platformy Azure i funkcję wyzwalacza HTTP, która może zwracać dodatkowe oświadczenia dla tokenu.

Wymagania wstępne

  • Podstawowa wiedza na temat pojęć omówionych w artykule Omówienie rozszerzeń uwierzytelniania niestandardowego.
  • Subskrypcja platformy Azure z możliwością tworzenia usługi Azure Functions. Jeśli nie masz istniejącego konta platformy Azure, utwórz konto bezpłatnej wersji próbnej lub skorzystaj z korzyści z subskrypcji programu Visual Studio podczas tworzenia konta.
  • Dzierżawa identyfikatora entra firmy Microsoft. W tym przewodniku z instrukcjami możesz użyć dzierżawy klienta lub pracowników.

W tym artykule opisano sposób tworzenia interfejsu API REST dla zdarzenia rozpoczęcia wystawiania tokenu przy użyciu biblioteki NuGet Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents i skonfigurowania jej do uwierzytelniania. Utworzysz funkcję wyzwalacza HTTP w programie Visual Studio lub Visual Studio Code, skonfigurujesz ją pod kątem uwierzytelniania i wdrożysz w witrynie Azure Portal, do której można uzyskać dostęp za pośrednictwem usługi Azure Functions.

Wymagania wstępne

Uwaga

Biblioteka NuGet Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents jest obecnie dostępna w wersji zapoznawczej. Kroki opisane w tym artykule mogą ulec zmianie. Aby zapewnić ogólną dostępność implementacji zdarzenia uruchamiania wystawiania tokenu, możesz to zrobić za pomocą witryny Azure Portal.

Tworzenie aplikacji funkcji platformy Azure

W witrynie Azure Portal utwórz aplikację funkcji platformy Azure i skojarzony zasób, zanim przejdziesz do tworzenia funkcji wyzwalacza HTTP.

  1. Zaloguj się do witryny Azure Portal jako co najmniej Administracja istrator aplikacji i Administracja istrator uwierzytelniania.

  2. W menu witryny Azure Portal lub na stronie głównej wybierz pozycję Utwórz zasób.

  3. Wyszukaj i wybierz pozycję Aplikacja funkcji, a następnie wybierz pozycję Utwórz.

  4. Na stronie Podstawy utwórz aplikację funkcji przy użyciu ustawień określonych w poniższej tabeli:

    Ustawienie Sugerowana wartość opis
    Subskrypcja Twoja subskrypcja Subskrypcja, w ramach której zostanie utworzona nowa aplikacja funkcji.
    Grupa zasobów myResourceGroup Wybierz i istniejącą grupę zasobów lub nazwę nowej, w której utworzysz aplikację funkcji.
    Nazwa aplikacji funkcji Nazwa unikatowa w skali globalnej Nazwa identyfikująca nową aplikację funkcji. Prawidłowe znaki to a-z (bez uwzględniania wielkości liter), 0-9i -.
    Wdrażanie kodu lub obrazu kontenera Kod Opcja publikowania plików kodu lub kontenera Docker. Na potrzeby tego samouczka wybierz pozycję Kod.
    Stos środowiska uruchomieniowego .NET Preferowany język programowania. Na potrzeby tego samouczka wybierz pozycję .NET.
    Wersja 6 (LTS) Proces Wersja środowiska uruchomieniowego platformy .NET. Oznacza, że można tworzyć i modyfikować funkcje w portalu, co jest zalecane w tym przewodniku
    Region Preferowany region Wybierz region, który znajduje się blisko Ciebie lub w pobliżu innych usług, do których mogą uzyskiwać dostęp funkcje.
    System operacyjny Windows System operacyjny jest wstępnie wybierany na podstawie wyboru stosu środowiska uruchomieniowego.
    Typ planu Zużycie (bezserwerowe) Plan hostingu określający sposób przydzielania zasobów do aplikacji funkcji.
  5. Wybierz pozycję Przejrzyj i utwórz , aby przejrzeć wybrane opcje konfiguracji aplikacji, a następnie wybierz pozycję Utwórz. Wdrożenie zajmuje kilka minut.

  6. Po wdrożeniu wybierz pozycję Przejdź do zasobu , aby wyświetlić nową aplikację funkcji.

Tworzenie funkcji wyzwalacza HTTP

Po utworzeniu aplikacji funkcji platformy Azure utwórz funkcję wyzwalacza HTTP w aplikacji. Wyzwalacz HTTP umożliwia wywoływanie funkcji z żądaniem HTTP i odwołuje się do niego niestandardowe rozszerzenie uwierzytelniania firmy Microsoft Entra.

  1. Na stronie Przegląd aplikacji funkcji wybierz okienko Funkcje i wybierz pozycję Utwórz funkcję w obszarze Utwórz w witrynie Azure Portal.
  2. W oknie Tworzenie funkcji pozostaw właściwość Środowisko programistyczne jako Programowanie w portalu. W obszarze Szablon wybierz pozycję Wyzwalacz HTTP.
  3. W obszarze Szczegóły szablonu wprowadź wartość CustomAuthenticationExtensionsAPI dla właściwości Nowa funkcja .
  4. W obszarze Poziom autoryzacji wybierz pozycję Funkcja.
  5. Wybierz pozycję Utwórz. Zrzut ekranu przedstawiający sposób wybierania środowiska projektowego i szablonu.

Edytowanie funkcji

Kod odczytuje przychodzący obiekt JSON, a identyfikator Entra firmy Microsoft wysyła obiekt JSON do interfejsu API. W tym przykładzie odczytuje wartość identyfikatora korelacji. Następnie kod zwraca kolekcję dostosowanych oświadczeń, w tym oryginalny CorrelationIdelement , ApiVersion funkcji platformy Azure, i DateOfBirthCustomRoles zwrócony do identyfikatora Entra firmy Microsoft.

  1. Z menu w obszarze Deweloper wybierz pozycję Kod i testowanie.

  2. Zastąp cały kod poniższym fragmentem kodu, a następnie wybierz pozycję Zapisz.

    #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 górnym menu wybierz pozycję Pobierz adres URL funkcji i skopiuj wartość adresu URL . Ten adres URL funkcji można użyć podczas konfigurowania niestandardowego rozszerzenia uwierzytelniania.

Tworzenie i tworzenie aplikacji funkcji platformy Azure

W tym kroku utworzysz interfejs API funkcji wyzwalacza HTTP przy użyciu środowiska IDE, zainstaluj wymagane pakiety NuGet i skopiuj przykładowy kod. Skompilujesz projekt i uruchomisz funkcję, aby wyodrębnić adres URL funkcji lokalnej.

Tworzenie aplikacji

Aby utworzyć aplikację funkcji platformy Azure, wykonaj następujące kroki:

  1. Otwórz program Visual Studio i wybierz pozycję Utwórz nowy projekt.
  2. Wyszukaj i wybierz pozycję Azure Functions, a następnie wybierz pozycję Dalej.
  3. Nadaj projektowi nazwę, taką jak AuthEventsTrigger. Dobrym pomysłem jest dopasowanie nazwy rozwiązania do nazwy projektu.
  4. Wybierz lokalizację projektu. Wybierz Dalej.
  5. Wybierz platformę .NET 6.0 (obsługa długoterminowa) jako platformę docelową.
  6. Wybierz pozycję Wyzwalacz HTTP jako typ funkcji , a poziom autoryzacji jest ustawiony na Wartość Funkcja. Wybierz pozycję Utwórz.
  7. W Eksplorator rozwiązań zmień nazwę pliku Function1.cs na AuthEventsTrigger.cs i zaakceptuj sugestię zmiany nazwy.

Instalowanie pakietów NuGet i kompilowanie projektu

Po utworzeniu projektu należy zainstalować wymagane pakiety NuGet i skompilować projekt.

  1. W górnym menu programu Visual Studio wybierz pozycję Projekt, a następnie pozycję Zarządzaj pakietami NuGet.
  2. Wybierz kartę Przeglądaj , a następnie wyszukaj i wybierz pozycję Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents w okienku po prawej stronie. Wybierz Zainstaluj.
  3. Zastosuj i zaakceptuj zmiany w wyświetlonych oknach podręcznych.

Dodawanie przykładowego kodu

Interfejs API funkcji jest źródłem dodatkowych oświadczeń dla tokenu. Na potrzeby tego artykułu na twardo odkodujemy wartości dla przykładowej aplikacji. W środowisku produkcyjnym można pobrać informacje o użytkowniku z zewnętrznego magazynu danych.

W pliku AuthEventsTrigger.cs zastąp całą zawartość pliku następującym kodem:

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);
            }
        }
    }
}

Kompilowanie i uruchamianie projektu lokalnie

Projekt został utworzony, a przykładowy kod został dodany. Korzystając ze środowiska IDE, musimy skompilować i uruchomić projekt lokalnie, aby wyodrębnić adres URL funkcji lokalnej.

  1. Przejdź do pozycji Kompiluj w górnym menu i wybierz pozycję Kompiluj rozwiązanie.
  2. Naciśnij klawisz F5 lub wybierz pozycję AuthEventsTrigger z górnego menu, aby uruchomić funkcję.
  3. Skopiuj adres URL funkcji z terminalu, który jest wyświetlany podczas uruchamiania funkcji. Może to być używane podczas konfigurowania niestandardowego rozszerzenia uwierzytelniania.

Warto przetestować funkcję lokalnie przed wdrożeniem jej na platformie Azure. Możemy użyć fikcyjnej treści JSON, która naśladuje żądanie wysyłane przez identyfikator Entra firmy Microsoft do interfejsu API REST. Użyj preferowanego narzędzia do testowania interfejsu API, aby wywołać funkcję bezpośrednio.

  1. W środowisku IDE otwórz local.settings.json i zastąp kod następującym kodem JSON. Możemy ustawić wartość "AuthenticationEvents__BypassTokenValidation" na true wartość na potrzeby testowania lokalnego.

    {
      "IsEncrypted": false,
      "Values": {
        "AzureWebJobsStorage": "",
        "AzureWebJobsSecretStorageType": "files",
        "FUNCTIONS_WORKER_RUNTIME": "dotnet",
        "AuthenticationEvents__BypassTokenValidation" : true
      }
    }
    
  2. Za pomocą preferowanego narzędzia do testowania interfejsu API utwórz nowe żądanie HTTP i ustaw metodę HTTP na POST.

  3. Użyj następującej treści JSON, która naśladuje żądanie wysyłane przez identyfikator Entra firmy Microsoft do interfejsu API REST.

    {
        "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. Wybierz pozycję Wyślij i powinna zostać odebrana odpowiedź JSON podobna do następującej:

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

Wdrażanie funkcji i publikowanie na platformie Azure

Funkcja musi zostać wdrożona na platformie Azure przy użyciu naszego środowiska IDE. Sprawdź, czy zalogowaliśmy się poprawnie na koncie platformy Azure, aby można było opublikować funkcję.

  1. W Eksplorator rozwiązań kliknij prawym przyciskiem myszy projekt i wybierz pozycję Publikuj.

  2. W obszarze Cel wybierz pozycję Azure, a następnie wybierz pozycję Dalej.

  3. Wybierz pozycję Aplikacja funkcji platformy Azure (Windows) dla określonego elementu docelowego, wybierz pozycję Aplikacja funkcji platformy Azure (Windows), a następnie wybierz pozycję Dalej.

  4. W wystąpieniu funkcji użyj listy rozwijanej Nazwa subskrypcji, aby wybrać subskrypcję, w ramach której zostanie utworzona nowa aplikacja funkcji.

  5. Wybierz miejsce, w którym chcesz opublikować nową aplikację funkcji, a następnie wybierz pozycję Utwórz nową.

  6. Na stronie Aplikacja funkcji (Windows) użyj ustawień aplikacji funkcji, jak określono w poniższej tabeli, a następnie wybierz pozycję Utwórz.

    Ustawienie Sugerowana wartość opis
    Nazwa/nazwisko Nazwa unikatowa w skali globalnej Nazwa identyfikująca nową aplikację funkcji. Prawidłowe znaki to a-z (bez uwzględniania wielkości liter), 0-9i -.
    Subskrypcja Twoja subskrypcja Subskrypcja, w ramach której jest tworzona nowa aplikacja funkcji.
    Grupa zasobów myResourceGroup Wybierz istniejącą grupę zasobów lub nadaj nowej nazwę, w której utworzysz aplikację funkcji.
    Typ planu Zużycie (bezserwerowe) Plan hostingu określający sposób przydzielania zasobów do aplikacji funkcji.
    Lokalizacja Preferowany region Wybierz region, który znajduje się blisko Ciebie lub w pobliżu innych usług, do których mogą uzyskiwać dostęp funkcje.
    Azure Storage Konto magazynu Środowisko uruchomieniowe usługi Functions wymaga konta magazynu platformy Azure. Wybierz pozycję Nowy, aby skonfigurować konto magazynu ogólnego przeznaczenia.
    Application Insights Wartość domyślna Funkcja usługi Azure Monitor. Jest to wybierane automatycznie, wybierz tę, której chcesz użyć lub skonfiguruj nową.
  7. Poczekaj chwilę na wdrożenie aplikacji funkcji. Po zamknięciu okna wybierz pozycję Zakończ.

  8. Zostanie otwarte nowe okienko Publikowanie . W górnej części wybierz pozycję Publikuj. Poczekaj kilka minut, aż aplikacja funkcji zostanie wdrożona i zostanie wyświetlona w witrynie Azure Portal.

Konfigurowanie uwierzytelniania dla funkcji platformy Azure

Istnieją trzy sposoby konfigurowania uwierzytelniania dla funkcji platformy Azure:

Domyślnie kod został skonfigurowany do uwierzytelniania w witrynie Azure Portal przy użyciu zmiennych środowiskowych. Użyj poniższych kart, aby wybrać preferowaną metodę implementowania zmiennych środowiskowych lub alternatywnie, zapoznaj się z wbudowanym uwierzytelnianiem i autoryzacją usługi aplikacja systemu Azure. Aby skonfigurować zmienne środowiskowe, użyj następujących wartości:

Nazwa/nazwisko Wartość
AuthenticationEvents__AudienceAppId Niestandardowy identyfikator aplikacji rozszerzenia uwierzytelniania skonfigurowany w temacie Konfigurowanie niestandardowego dostawcy oświadczeń dla zdarzenia wystawiania tokenu
AuthenticationEvents__AuthorityUrl • Dzierżawa pracowników https://login.microsoftonline.com/<tenantID>
• Dzierżawa zewnętrzna https://<mydomain>.ciamlogin.com
AuthenticationEvents__AuthorizedPartyAppId 99045fe1-7639-4a75-9d4a-577b6ca3810f lub inna autoryzowana strona

Konfigurowanie uwierzytelniania w witrynie Azure Portal przy użyciu zmiennych środowiskowych

  1. Zaloguj się do witryny Azure Portal jako co najmniej Administracja istrator aplikacji lub Administracja istrator uwierzytelniania.
  2. Przejdź do utworzonej aplikacji funkcji i w obszarze Ustawienia wybierz pozycję Konfiguracja.
  3. W obszarze Ustawienia aplikacji wybierz pozycję Nowe ustawienie aplikacji i dodaj zmienne środowiskowe z tabeli i skojarzonych z nimi wartości.
  4. Wybierz pozycję Zapisz , aby zapisać ustawienia aplikacji.

Następny krok