Usare le identità utente nell'autenticazione di Servizio app di Azure

Questo articolo illustra come usare le identità utente quando si usa l'autenticazione e l'autorizzazione predefinita in servizio app.

Accedere alle attestazioni utente nel codice dell'app

Per tutti i framework di linguaggio, servizio app rende disponibili le attestazioni nel token in ingresso (sia da un utente finale autenticato che da un'applicazione client) per il codice immettendole nelle intestazioni della richiesta. Le richieste esterne non sono consentite per impostare queste intestazioni, quindi sono presenti solo se impostate da 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à client.
X-MS-CLIENT-PRINCIPAL-ID Identificatore per il chiamante impostato dal provider di identità.
X-MS-CLIENT-PRINCIPAL-NAME Nome leggibile per il chiamante impostato dal provider di identità, ad esempio Email Indirizzo, Nome entità utente.
X-MS-CLIENT-PRINCIPAL-IDP Nome del provider di identità usato dall'autenticazione di servizio app.

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

Nota

I framework di linguaggio diversi possono presentare queste intestazioni al codice dell'app in formati diversi, ad esempio maiuscole o minuscole.

Il codice scritto in qualsiasi linguaggio o framework può ottenere le informazioni necessarie da queste intestazioni. La decodifica dell'intestazione dell'entità client illustra questo processo. Per alcuni framework, la piattaforma offre anche opzioni aggiuntive che potrebbero essere 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 rispetto a quello che si noterebbe se l'elaborazione diretta del token. Il payload decodificato è strutturato come segue:

{
    "auth_typ": "",
    "claims": [
        {
            "typ": "",
            "val": ""
        }
    ],
    "name_typ": "",
    "role_typ": ""
}
Proprietà Type Descrizione
auth_typ string Nome del provider di identità usato dall'autenticazione di servizio app.
claims matrice di oggetti Matrice di oggetti che rappresentano le attestazioni disponibili. Ogni oggetto contiene typ e val proprietà.
typ string Nome dell'attestazione. Potrebbe essere stato soggetto al mapping delle attestazioni predefinite 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 ne viene definito uno.
role_typ string Tipo di attestazione del ruolo, che è in genere un URI che fornisce informazioni sullo schema sull'attestazione role se viene definito.

Per elaborare questa intestazione, l'app dovrà decodificare il payload e scorrere la claims matrice per trovare le attestazioni di interesse. Può essere utile convertire questi in una rappresentazione usata dal framework del linguaggio dell'app. Ecco un esempio di questo processo in C# che costruisce un tipo ClaimsPrincipal per l'app da usare:

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 da Tomcat servlet.

Per Funzioni di Azure, non è popolato per il codice .NET, ClaimsPrincipal.Current 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 la popolamento dell'utente corrente con l'autenticazione servizio app. Per altre informazioni, è possibile leggere le informazioni sul wiki Microsoft.Identity.Web o vedere questa esercitazione illustrata 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