共用方式為


在 Azure App Service 驗證中使用使用者身分識別

本文說明如何在 Azure App Service 中使用 內建驗證和授權 時,使用使用者身分識別。

先決條件

在 Azure App Service 上執行且已啟用 App Service 驗證/授權模組的 Web 應用程式。

在應用程式程式碼中存取使用者宣告

您的應用程式的已驗證終端使用者或用戶端應用程式會在傳入權杖中提出宣告。 App Service 會透過將宣告插入到要求標頭中,讓宣告可供您的程式碼使用。 不允許外部要求設定這些標頭,因此只有在App Service 設定這些標頭時才會存在。

您可以使用 App Service 驗證所提供的宣告資訊,在應用程式程式代碼中執行授權檢查。 任何語言或架構中的程式代碼都可以從要求標頭取得所需的資訊。 某些程式代碼架構提供可能更方便的額外選項。 請參閱 架構特定的替代方案

下表描述一些範例標頭:

頁首 描述
X-MS-CLIENT-PRINCIPAL 可用宣告的 Base64 編碼 JSON 表示法。 如需詳細資訊,請參閱 譯碼用戶端主體標頭
X-MS-CLIENT-PRINCIPAL-ID 識別提供者為呼叫端設定的標識碼。
X-MS-CLIENT-PRINCIPAL-NAME 識別提供者為呼叫者設定的人類可讀取名稱,例如電子郵件地址或用戶主體名稱。
X-MS-CLIENT-PRINCIPAL-IDP App Service 驗證所使用的識別提供者名稱。

類似的標頭會公開 提供者令牌。 例如,Microsoft Entra 會視情況設定 X-MS-TOKEN-AAD-ACCESS-TOKENX-MS-TOKEN-AAD-ID-TOKEN 提供者令牌標頭。

附註

App Service 讓要求標頭可供所有語言架構使用。 這些應用程式程式碼的標題可能會因不同的語言架構,而以不同的格式呈現,例如小寫或標題字體。

解碼客戶端主體標頭

標頭 X-MS-CLIENT-PRINCIPAL 包含Base64編碼 JSON 中可用宣告的完整集合。 若要處理此標頭,您的應用程式必須解碼承載,並遍歷 claims 陣列以尋找相關的宣告。

附註

這些宣告會經歷預設宣告對應程式,因此某些名稱可能與令牌中顯示的名稱不同。

譯碼的承載結構如下所示:

{
    "auth_typ": "",
    "claims": [
        {
            "typ": "",
            "val": ""
        }
    ],
    "name_typ": "",
    "role_typ": ""
}

下表描述屬性。

屬性 類型 描述
auth_typ 字串 App Service 驗證所使用的識別提供者名稱。
claims 陣列 物件陣列,表示可用的權利要求。 每個物件都包含 typval 屬性。
typ 字串 宣告的名稱可能會受到預設宣告映射的影響,並且與令牌中的相應宣告不同。
val 字串 宣告的值。
name_typ 字串 名稱宣告類型,通常是在定義宣告時提供 name 宣告配置資訊的 URI。
role_typ 字串 角色宣告類型,通常是在定義宣告時提供 role 宣告配置資訊的 URI。

為了方便起見,您可以將宣告轉換成應用程式語言架構所使用的表示法。 下列 C# 範例會建構應用程式所需的ClaimsPrincipal類型。

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

此時,程式代碼可以遍歷 principal.Claims 以檢查宣告,作為驗證過程的一部分。 或者,您可以將 principal.Claims 轉換為標準物件,並在要求管線中稍後使用它來進行這些檢查。 您也可以使用該物件來建立用戶數據和其他用途的關聯。

函式的其他部分會執行這種轉換,以建立可在其他 .NET 程式代碼中使用的 ClaimsPrincipal

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

架構特定替代方案

附註

為了讓宣告對應運作,您必須為您的應用程式啟用權杖存放區

使用 API 存取使用者宣告

如果應用程式已啟用 令牌存放區 ,您也可以呼叫 /.auth/me 以取得已驗證使用者的其他詳細數據。