Creare un'API REST per un evento di avvio del rilascio di token in Funzioni di Azure

Questo articolo descrive come creare un'API REST con un evento di avvio del rilascio di token usando Funzioni di Azure nella portale di Azure. Si crea un'app per le funzioni di Azure e una funzione trigger HTTP che può restituire attestazioni aggiuntive per il token.

Prerequisiti

  • Conoscenza di base dei concetti trattati in Panoramica delle estensioni di autenticazione personalizzate.
  • Una sottoscrizione di Azure con la possibilità di creare Funzioni di Azure. Se non si ha un account Azure esistente, iscriversi per ottenere una versione di valutazione gratuita o usare i vantaggi della sottoscrizione di Visual Studio quando si crea un account.
  • Tenant di Microsoft Entra ID. È possibile usare un tenant del cliente o della forza lavoro per questa guida pratica.

Questo articolo descrive come creare un'API REST per un evento di avvio del rilascio di token usando la libreria NuGet Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents e impostarla per l'autenticazione. Si creerà una funzione trigger HTTP in Visual Studio o Visual Studio Code, la si configurerà per l'autenticazione e la si distribuirà nel portale di Azure, in cui è possibile accedervi tramite Funzioni di Azure.

Prerequisiti

Nota

La libreria NuGet Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents è attualmente in anteprima. I passaggi descritti in questo articolo sono soggetti a modifiche. Per l'implementazione della disponibilità generale dell'implementazione di un evento di avvio del rilascio di token, è possibile farlo usando il portale di Azure.

Creare l'app per le funzioni di Azure

Nella portale di Azure creare un'app per le funzioni di Azure e la risorsa associata prima di continuare a creare la funzione trigger HTTP.

  1. Accedere al portale di Azure almeno come amministratore dell'applicazione e amministratore dell'autenticazione.

  2. Nel menu del portale di Azure o dalla pagina Home selezionare Crea una risorsa.

  3. Cercare e selezionare App per le funzioni e selezionare Crea.

  4. Nella pagina Informazioni di base creare un'app per le funzioni usando le impostazioni specificate nella tabella seguente:

    Impostazione Valore suggerito Descrizione
    Abbonamento Sottoscrizione in uso Sottoscrizione in cui verrà creata la nuova app per le funzioni.
    Gruppo di risorse myResourceGroup Selezionare e esistente un gruppo di risorse o assegnare un nome al nuovo gruppo di risorse in cui si creerà l'app per le funzioni.
    Nome dell'app per le funzioni Nome globalmente univoco Nome che identifica la nuova app per le funzioni. I caratteri validi sono a-z (senza distinzione tra maiuscole e minuscole), 0-9 e -.
    Distribuire codice o immagine del contenitore Codice Opzione per la pubblicazione di file di codice o di un contenitore Docker. Per questa esercitazione selezionare Codice.
    Stack di runtime .NET Il linguaggio di programmazione preferito. Per questa esercitazione selezionare .NET.
    Versione 6 (LTS) in-process Versione del runtime .NET. In-process indica che è possibile creare e modificare funzioni nel portale, consigliato per questa guida
    Area Area preferita Selezionare un'area vicina a sé o vicina ad altri servizi a cui le funzioni possono accedere.
    Sistema operativo Windows Il sistema operativo è pre-selezionato in base alla selezione dello stack di runtime.
    Tipo di piano Consumo (serverless) Piano di hosting che definisce come vengono allocate le risorse all'app per le funzioni.
  5. Selezionare Rivedi e crea per esaminare le selezioni di configurazione dell'app e quindi selezionare Crea. La distribuzione richiede alcuni minuti.

  6. Dopo la distribuzione, selezionare Vai alla risorsa per visualizzare la nuova app per le funzioni.

Creare una funzione trigger HTTP

Dopo aver creato l'app per le funzioni di Azure, creare una funzione trigger HTTP all'interno dell'app. Il trigger HTTP consente di richiamare una funzione con una richiesta HTTP e fa riferimento all'estensione di autenticazione personalizzata Di Microsoft Entra.

  1. Nella pagina Panoramica dell'app per le funzioni selezionare il riquadro Funzioni e selezionare Crea funzione in Crea in portale di Azure.
  2. Nella finestra Crea funzione lasciare la proprietà Ambiente di sviluppo come Sviluppo nel portale. In Modello selezionare Trigger HTTP.
  3. In Dettagli modello immettere CustomAuthenticationExtensionsAPI per la proprietà Nuova funzione.
  4. Per Livello di autorizzazione selezionare Funzione.
  5. Seleziona Crea. Screenshot che mostra come scegliere l'ambiente di sviluppo e il modello.

Modificare la funzione

Il codice legge l'oggetto JSON in ingresso e l'ID Microsoft Entra invia l'oggetto JSON all'API. In questo esempio legge il valore dell'ID di correlazione. Il codice restituisce quindi una raccolta di attestazioni personalizzate, tra cui l'originale CorrelationId, della ApiVersion funzione di Azure, un DateOfBirth oggetto e CustomRoles restituito all'ID Microsoft Entra.

  1. Dal menu, in Sviluppo, selezionare Codice e test.

  2. Sostituire l'intero codice con il frammento di codice seguente, quindi selezionare Salva.

    #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. Nel menu in alto selezionare Recupera URL funzione e copiare il valore dell'URL. Questo URL di funzione può essere usato durante la configurazione di un'estensione di autenticazione personalizzata.

Creare e compilare l'app per le funzioni di Azure

In questo passaggio si crea un'API della funzione trigger HTTP usando l'IDE, si installano i pacchetti NuGet necessari e si copiano nel codice di esempio. Compilare il progetto ed eseguire la funzione per estrarre l'URL della funzione locale.

Creare l'applicazione

Per creare un'app per le funzioni di Azure, seguire questa procedura:

  1. Aprire Visual Studio e selezionare Crea un nuovo progetto.
  2. Cercare e selezionare Funzioni di Azure, quindi selezionare Avanti.
  3. Assegnare un nome al progetto, ad esempio AuthEventsTrigger. È consigliabile trovare una corrispondenza con il nome della soluzione con il nome del progetto.
  4. Selezionare una località per il progetto. Selezionare Avanti.
  5. Selezionare .NET 6.0 (supporto a lungo termine) come framework di destinazione.
  6. Selezionare Trigger HTTP come tipo di funzione e il livello di autorizzazione è impostato su Funzione. Seleziona Crea.
  7. Nella Esplora soluzioni rinominare il file di Function1.cs in AuthEventsTrigger.cs e accettare il suggerimento per la ridenominazione.

Installare pacchetti NuGet e compilare il progetto

Dopo aver creato il progetto, è necessario installare i pacchetti NuGet necessari e compilare il progetto.

  1. Nel menu in alto di Visual Studio selezionare Progetto, quindi Gestisci pacchetti NuGet.
  2. Selezionare la scheda Sfoglia , quindi cercare e selezionare Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents nel riquadro a destra. Selezionare Installa.
  3. Applicare e accettare le modifiche nei popup visualizzati.

Aggiungere il codice di esempio

L'API della funzione è l'origine di attestazioni aggiuntive per il token. Ai fini di questo articolo, vengono hardcodati i valori per l'app di esempio. Nell'ambiente di produzione è possibile recuperare informazioni sull'utente dall'archivio dati esterno.

Nel file AuthEventsTrigger.cs sostituire l'intero contenuto del file con il codice seguente:

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

Compilare ed eseguire il progetto in locale

Il progetto è stato creato ed è stato aggiunto il codice di esempio. Usando l'IDE, è necessario compilare ed eseguire il progetto in locale per estrarre l'URL della funzione locale.

  1. Passare a Compila nel menu in alto e selezionare Compila soluzione.
  2. Premere F5 o selezionare AuthEventsTrigger dal menu in alto per eseguire la funzione.
  3. Copiare l'URL della funzione dal terminale che viene visualizzato quando si esegue la funzione. Questa operazione può essere usata durante la configurazione di un'estensione di autenticazione personalizzata.

È consigliabile testare la funzione in locale prima di distribuirla in Azure. È possibile usare un corpo JSON fittizio che imita la richiesta inviata da Microsoft Entra ID all'API REST. Usare lo strumento di test api preferito per chiamare direttamente la funzione.

  1. Nell'IDE aprire local.settings.json e sostituire il codice con il codice JSON seguente. È possibile impostare su "AuthenticationEvents__BypassTokenValidation" true per scopi di test locali.

    {
      "IsEncrypted": false,
      "Values": {
        "AzureWebJobsStorage": "",
        "AzureWebJobsSecretStorageType": "files",
        "FUNCTIONS_WORKER_RUNTIME": "dotnet",
        "AuthenticationEvents__BypassTokenValidation" : true
      }
    }
    
  2. Usando lo strumento di test api preferito, creare una nuova richiesta HTTP e impostare il metodo HTTP su POST.

  3. Usare il corpo JSON seguente che imita la richiesta inviata da Microsoft Entra ID all'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. Selezionare Invia e si dovrebbe ricevere una risposta JSON simile alla seguente:

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

Distribuire la funzione e pubblicare in Azure

La funzione deve essere distribuita in Azure usando l'IDE. Verificare di aver eseguito correttamente l'accesso all'account Azure in modo che la funzione possa essere pubblicata.

  1. Nella Esplora soluzioni fare clic con il pulsante destro del mouse sul progetto e scegliere Pubblica.

  2. In Destinazione selezionare Azure, quindi selezionare Avanti.

  3. Selezionare App per le funzioni di Azure (Windows) per La destinazione specifica, selezionare App per le funzioni di Azure (Windows) e quindi selezionare Avanti.

  4. Nell'istanza di Function usare l'elenco a discesa Nome sottoscrizione per selezionare la sottoscrizione in cui verrà creata la nuova app per le funzioni.

  5. Selezionare la posizione in cui si vuole pubblicare la nuova app per le funzioni e selezionare Crea nuovo.

  6. Nella pagina App per le funzioni (Windows) usare le impostazioni dell'app per le funzioni come specificato nella tabella seguente, quindi selezionare Crea.

    Impostazione Valore suggerito Description
    Nome Nome globalmente univoco Nome che identifica la nuova app per le funzioni. I caratteri validi sono a-z (senza distinzione tra maiuscole e minuscole), 0-9 e -.
    Abbonamento Sottoscrizione in uso Sottoscrizione in cui viene creata la nuova app per le funzioni.
    Gruppo di risorse myResourceGroup Selezionare un gruppo di risorse esistente o denominarne uno nuovo in cui si creerà l'app per le funzioni.
    Tipo di piano Consumo (serverless) Piano di hosting che definisce come vengono allocate le risorse all'app per le funzioni.
    Location Area preferita Selezionare un'area vicina a sé o vicina ad altri servizi a cui le funzioni possono accedere.
    Archiviazione di Azure Account di archiviazione L'account di archiviazione di Azure è necessario per il runtime di Funzioni. Selezionare Nuovo per configurare un account di archiviazione per utilizzo generico.
    Application Insights Predefinita Funzionalità di Monitoraggio di Azure. Questa opzione è selezionata automaticamente, selezionare quella che si vuole usare o configurare una nuova.
  7. Attendere alcuni istanti per la distribuzione dell'app per le funzioni. Al termine della finestra, selezionare Fine.

  8. Verrà aperto un nuovo riquadro Pubblica . Nella parte superiore selezionare Pubblica. Attendere alcuni minuti che l'app per le funzioni venga distribuita e visualizzata nella portale di Azure.

Configurare l'autenticazione per la funzione di Azure

Esistono tre modi per configurare l'autenticazione per la funzione di Azure:

Per impostazione predefinita, il codice è stato configurato per l'autenticazione nel portale di Azure usando le variabili di ambiente. Usare le schede seguenti per selezionare il metodo preferito per implementare le variabili di ambiente o, in alternativa, fare riferimento all'autenticazione e all'autorizzazione predefiniti del servizio app Azure. Per configurare le variabili di ambiente, usare i valori seguenti:

Nome Valore
AuthenticationEvents__AudienceAppId ID app dell'estensione di autenticazione personalizzata configurato in Configurare un provider di attestazioni personalizzato per un evento di rilascio di token
AuthenticationEvents__AuthorityUrl • Tenant della forza lavoro https://login.microsoftonline.com/<tenantID>
• Tenant esterno https://<mydomain>.ciamlogin.com/<tenantID>
AuthenticationEvents__AuthorizedPartyAppId 99045fe1-7639-4a75-9d4a-577b6ca3810f o un'altra parte autorizzata

Configurare l'autenticazione nel portale di Azure usando le variabili di ambiente

  1. Accedere al portale di Azure almeno come amministratore dell'applicazione o amministratore dell'autenticazione.
  2. Passare all'app per le funzioni creata e in Impostazioni selezionare Configurazione.
  3. In Impostazioni applicazione selezionare Nuova impostazione applicazione e aggiungere le variabili di ambiente dalla tabella e i relativi valori associati.
  4. Selezionare Salva per salvare le impostazioni dell'applicazione.

Passaggio successivo