Usare le identità utente nell'autenticazione del servizio app di Azure

Questo articolo illustra come usare le identità utente quando si usano l'autenticazione e l'autorizzazione predefinite nel servizio app.

Accedere alle attestazioni utente nel codice dell'app

Per tutti i framework del linguaggio, il servizio app rende le attestazioni nel token in ingresso (da un utente finale autenticato o un'applicazione client) disponibili per il codice inserendole nelle intestazioni della richiesta. Alle richieste esterne non è consentito impostare queste intestazioni, che sono quindi presenti solo se impostate dal servizio app. Ecco alcune intestazioni di esempio:

Intestazione Descrizione
X-MS-CLIENT-PRINCIPAL Rappresentazione JSON con codifica Base64 delle attestazioni disponibili. Per altre informazioni, vedere Decodifica dell'intestazione dell'entità di client.
X-MS-CLIENT-PRINCIPAL-ID Identificatore del chiamante impostato dal provider di identità.
X-MS-CLIENT-PRINCIPAL-NAME Nome leggibile del chiamante impostato dal provider di identità, ad esempio l'indirizzo e-mail o il nome dell'entità utente.
X-MS-CLIENT-PRINCIPAL-IDP Nome del provider di identità usato dall'autenticazione del servizio app.

I token del provider vengono esposti anche tramite intestazioni simili. Ad esempio, anche Microsoft Entra imposta X-MS-TOKEN-AAD-ACCESS-TOKEN e X-MS-TOKEN-AAD-ID-TOKEN in base alle esigenze.

Nota

Framework di linguaggio diversi potrebbero presentare queste intestazioni al codice dell'app in formati diversi, ad esempio lettere minuscole o maiuscole.

Il codice scritto in qualsiasi linguaggio o framework può ottenere le informazioni necessarie da queste intestazioni. La decodifica dell'intestazione dell'entità client copre questo processo. Per alcuni framework, la piattaforma offre anche opzioni aggiuntive che potrebbero risultare più convenienti.

Decodifica dell'intestazione dell'entità client

X-MS-CLIENT-PRINCIPAL contiene il set completo di attestazioni disponibili come JSON con codifica Base64. Queste attestazioni passano attraverso un processo di mapping delle attestazioni predefinito, quindi alcuni potrebbero avere nomi diversi da quelli che si vedrebbero se elaborassero direttamente il token. Il payload decodificato è strutturato come segue:

{
    "auth_typ": "",
    "claims": [
        {
            "typ": "",
            "val": ""
        }
    ],
    "name_typ": "",
    "role_typ": ""
}
Proprietà Type Descrzione
auth_typ stringa Nome del provider di identità usato dall'autenticazione del servizio app.
claims matrice di oggetti Matrice di oggetti che rappresentano le attestazioni disponibili. Ogni oggetto contiene proprietà typ e val.
typ string Nome dell'attestazione. Potrebbe essere soggetto al mapping delle attestazioni predefinito e potrebbe essere diverso dall'attestazione corrispondente contenuta in un token.
val string Valore dell'attestazione.
name_typ string Tipo di attestazione del nome, che in genere è un URI che fornisce informazioni sullo schema sull'attestazione name, se definita.
role_typ string Tipo di attestazione del ruolo, che in genere è un URI che fornisce informazioni sullo schema sull'attestazione role, se definita.

Per elaborare questa intestazione, l'app deve decodificare il payload ed eseguire l'iterazione della matrice claims per trovare le attestazioni di interesse. Potrebbe essere utile convertirli in una rappresentazione usata dal framework del linguaggio dell'app. Ecco un esempio di questo processo in C# che costruisce un tipo ClaimsPrincipal da usare per l'app:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using Microsoft.AspNetCore.Http;

public static class ClaimsPrincipalParser
{
    private class ClientPrincipalClaim
    {
        [JsonPropertyName("typ")]
        public string Type { get; set; }
        [JsonPropertyName("val")]
        public string Value { get; set; }
    }

    private class ClientPrincipal
    {
        [JsonPropertyName("auth_typ")]
        public string IdentityProvider { get; set; }
        [JsonPropertyName("name_typ")]
        public string NameClaimType { get; set; }
        [JsonPropertyName("role_typ")]
        public string RoleClaimType { get; set; }
        [JsonPropertyName("claims")]
        public IEnumerable<ClientPrincipalClaim> Claims { get; set; }
    }

    public static ClaimsPrincipal Parse(HttpRequest req)
    {
        var principal = new ClientPrincipal();

        if (req.Headers.TryGetValue("x-ms-client-principal", out var header))
        {
            var data = header[0];
            var decoded = Convert.FromBase64String(data);
            var json = Encoding.UTF8.GetString(decoded);
            principal = JsonSerializer.Deserialize<ClientPrincipal>(json, new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
        }

        /** 
         *  At this point, the code can iterate through `principal.Claims` to
         *  check claims as part of validation. Alternatively, we can convert
         *  it into a standard object with which to perform those checks later
         *  in the request pipeline. That object can also be leveraged for 
         *  associating user data, etc. The rest of this function performs such
         *  a conversion to create a `ClaimsPrincipal` as might be used in 
         *  other .NET code.
         */

        var identity = new ClaimsIdentity(principal.IdentityProvider, principal.NameClaimType, principal.RoleClaimType);
        identity.AddClaims(principal.Claims.Select(c => new Claim(c.Type, c.Value)));
        
        return new ClaimsPrincipal(identity);
    }
}

Alternative specifiche del framework

Per le app ASP.NET 4.6, il servizio app popola ClaimsPrincipal.Current con le attestazioni dell'utente autenticato, quindi è possibile seguire il modello di codice .NET standard, incluso l'attributo [Authorize]. Analogamente, per le app PHP, il servizio app popola la variabile _SERVER['REMOTE_USER']. Per le app Java, le attestazioni sono accessibili dal servlet Tomcat.

Per Funzioni di Azure, ClaimsPrincipal.Current non viene popolato per il codice .NET, ma è comunque possibile trovare le attestazioni utente nelle intestazioni della richiesta o ottenere l'oggetto ClaimsPrincipal dal contesto della richiesta o anche tramite un parametro di associazione. Per altre informazioni, vedere Uso delle identità client in Funzioni di Azure.

Per .NET Core, Microsoft.Identity.Web supporta il popolamento dell'utente corrente con l'autenticazione del servizio app. È possibile leggere altre informazioni nel wiki Microsoft.Identity.Web oppure vedere la dimostrazione in questa esercitazione per un'app Web che accede a Microsoft Graph.

Nota

Per il funzionamento del mapping delle attestazioni, è necessario abilitare l'archivio token.

Accedere alle attestazioni utente usando l'API

Se l'archivio token è abilitato per l'app, è anche possibile ottenere altri dettagli sull'utente autenticato chiamando /.auth/me.

Passaggi successivi