Praca z tożsamościami użytkowników w Azure App Service uwierzytelniania

W tym artykule pokazano, jak pracować z tożsamościami użytkowników podczas korzystania z wbudowanego uwierzytelniania i autoryzacji w App Service.

Uzyskiwanie dostępu do oświadczeń użytkowników w kodzie aplikacji

Dla wszystkich struktur językowych App Service zgłasza oświadczenia w tokenie przychodzącym (niezależnie od uwierzytelnionego użytkownika końcowego lub aplikacji klienckiej) dostępne dla kodu przez wstrzyknięcie ich do nagłówków żądania. Żądania zewnętrzne nie mogą ustawiać tych nagłówków, więc są obecne tylko w przypadku ustawiania ich przez App Service. Oto przykładowe nagłówki:

Nagłówek Opis
X-MS-CLIENT-PRINCIPAL Zakodowana w formacie JSON reprezentacja dostępnych oświadczeń w formacie Base64. Aby uzyskać więcej informacji, zobacz Dekodowanie nagłówka podmiotu zabezpieczeń klienta.
X-MS-CLIENT-PRINCIPAL-ID Identyfikator elementu wywołującego ustawionego przez dostawcę tożsamości.
X-MS-CLIENT-PRINCIPAL-NAME Czytelna dla człowieka nazwa obiektu wywołującego ustawionego przez dostawcę tożsamości, np. adres Email, główna nazwa użytkownika.
X-MS-CLIENT-PRINCIPAL-IDP Nazwa dostawcy tożsamości używanego przez uwierzytelnianie App Service.

Tokeny dostawcy są również udostępniane za pośrednictwem podobnych nagłówków. Na przykład dostawca tożsamości firmy Microsoft ustawia X-MS-TOKEN-AAD-ACCESS-TOKEN również i X-MS-TOKEN-AAD-ID-TOKEN odpowiednio.

Uwaga

Różne struktury językowe mogą przedstawiać te nagłówki do kodu aplikacji w różnych formatach, takich jak małe litery lub wielkość tytułu.

Kod napisany w dowolnym języku lub strukturze może uzyskać informacje potrzebne z tych nagłówków. Dekodowanie nagłówka podmiotu zabezpieczeń klienta obejmuje ten proces. W przypadku niektórych struktur platforma udostępnia również dodatkowe opcje, które mogą być wygodniejsze.

Dekodowanie nagłówka podmiotu zabezpieczeń klienta

X-MS-CLIENT-PRINCIPAL zawiera pełny zestaw dostępnych oświadczeń jako kodowany w formacie Base64 JSON. Te oświadczenia przechodzą przez domyślny proces mapowania oświadczeń, więc niektóre mogą mieć różne nazwy niż w przypadku bezpośredniego przetwarzania tokenu. Zdekodowany ładunek jest ustrukturyzowany w następujący sposób:

{
    "auth_typ": "",
    "claims": [
        {
            "typ": "",
            "val": ""
        }
    ],
    "name_typ": "",
    "role_typ": ""
}
Właściwość Typ Opis
auth_typ ciąg Nazwa dostawcy tożsamości używanego przez uwierzytelnianie App Service.
claims tablica obiektów Tablica obiektów reprezentujących dostępne oświadczenia. Każdy obiekt zawiera typ i val właściwości.
typ ciąg Nazwa oświadczenia. Może to być przedmiotem mapowania oświadczeń domyślnych i może być inny niż odpowiednie oświadczenie zawarte w tokenie.
val ciąg Wartość oświadczenia.
name_typ ciąg Typ oświadczenia nazwy, który jest zazwyczaj identyfikatorem URI dostarczającym informacje o schemacie oświadczenia name , jeśli jest zdefiniowany.
role_typ ciąg Typ oświadczenia roli, który jest zazwyczaj identyfikatorem URI dostarczającym informacje role o schemacie oświadczenia, jeśli jest zdefiniowany.

Aby przetworzyć ten nagłówek, aplikacja będzie musiała zdekodować ładunek i iterować go przez tablicę claims , aby znaleźć interesujące oświadczenia. Można je łatwo przekonwertować na reprezentację używaną przez platformę języka aplikacji. Oto przykład tego procesu w języku C#, który tworzy typ ClaimsPrincipal dla aplikacji do użycia:

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

Alternatywy specyficzne dla struktury

W przypadku aplikacji ASP.NET 4.6 App Service wypełnia wartość ClaimsPrincipal.Current z oświadczeniami uwierzytelnioowanego użytkownika, aby można było postępować zgodnie ze standardowym wzorcem kodu platformy .NET, w tym atrybutem[Authorize]. Podobnie w przypadku aplikacji PHP App Service wypełnia zmienną_SERVER['REMOTE_USER']. W przypadku aplikacji Java oświadczenia są dostępne z serwletu Tomcat.

W przypadku Azure FunctionsClaimsPrincipal.Current nie jest wypełniany dla kodu platformy .NET, ale nadal można znaleźć oświadczenia użytkownika w nagłówkach żądania lub pobrać ClaimsPrincipal obiekt z kontekstu żądania, a nawet za pomocą parametru powiązania. Aby uzyskać więcej informacji, zobacz Praca z tożsamościami klientów w Azure Functions.

W przypadku platformy .NET Core usługa Microsoft.Identity.Web obsługuje wypełnianie bieżącego użytkownika za pomocą uwierzytelniania App Service. Aby dowiedzieć się więcej, możesz przeczytać o niej w witrynie typu wiki Microsoft.Identity.Web lub zapoznać się z nią w tym samouczku dotyczącym aplikacji internetowej, która uzyskuje dostęp do programu Microsoft Graph.

Uwaga

Aby mapowanie oświadczeń działało, należy włączyć magazyn tokenów.

Uzyskiwanie dostępu do oświadczeń użytkowników przy użyciu interfejsu API

Jeśli magazyn tokenów jest włączony dla aplikacji, możesz również uzyskać inne szczegóły dotyczące uwierzytelnionego użytkownika, wywołując metodę /.auth/me.

Następne kroki