العمل مع هويات المستخدمين في مصادقة Azure App Service

توضح لك هذه المقالة كيفية العمل مع هويات المستخدم عند استخدام المصادقة والتخويل المضمنين في App Service.

الوصول إلى مطالبات المستخدم في التعليمة البرمجية للتطبيق

بالنسبة لجميع أطر عمل اللغات، توفر App Service المطالبات في الرمز المميز الوارد (سواء من مستخدم نهائي مصادق عليه أو تطبيق عميل) للتعليمات البرمجية الخاصة بك عن طريق إدخالها في عناوين الطلب. لا يسمح للطلبات الخارجية بتعيين هذه العناوين، لذا فهي موجودة فقط إذا تم تعيينها بواسطة App Service. تتضمن بعض الأمثلة على العناوين ما يلي:

الرأس ‏‏الوصف
X-MS-CLIENT-PRINCIPAL تمثيل JSON المشفر Base64 للمطالبات المتاحة. لمزيد من المعلومات، راجع فك ترميز رأس العميل الأساسي.
X-MS-CLIENT-PRINCIPAL-ID معرف للمتصل تم تعيينه بواسطة موفر الهوية.
X-MS-CLIENT-PRINCIPAL-NAME اسم قابل للقراءة للإنسان للمتصل تم تعيينه بواسطة موفر الهوية، على سبيل المثال عنوان البريد الإلكتروني، اسم المستخدم الأساسي.
X-MS-CLIENT-PRINCIPAL-IDP اسم موفر الهوية المستخدم بواسطة App Service Authentication.

يتم أيضا عرض رموز الموفر المميزة من خلال عناوين مماثلة. على سبيل المثال، يقوم Microsoft Entra أيضا بتعيين X-MS-TOKEN-AAD-ACCESS-TOKEN و X-MS-TOKEN-AAD-ID-TOKEN حسب الاقتضاء.

إشعار

قد تقدم أطر عمل اللغات المختلفة هذه العناوين إلى التعليمات البرمجية للتطبيق بتنسيقات مختلفة، مثل الأحرف الصغيرة أو حالة العنوان.

يمكن أن تحصل التعليمات البرمجية المكتوبة بأي لغة أو إطار عمل على المعلومات التي تحتاجها من هذه العناوين. يغطي فك ترميز رأس العميل الأساسي هذه العملية. بالنسبة لبعض الأطر، يوفر النظام الأساسي أيضا خيارات إضافية قد تكون أكثر ملاءمة.

فك ترميز رأس العميل الأساسي

X-MS-CLIENT-PRINCIPAL يحتوي على المجموعة الكاملة من المطالبات المتاحة ك JSON المشفرة Base64. تمر هذه المطالبات بعملية تعيين المطالبات الافتراضية، لذلك قد يكون لبعضها أسماء مختلفة عما قد ترى إذا كانت معالجة الرمز المميز مباشرة. يتم تنظيم الحمولة التي تم فك ترميزها على النحو التالي:

{
    "auth_typ": "",
    "claims": [
        {
            "typ": "",
            "val": ""
        }
    ],
    "name_typ": "",
    "role_typ": ""
}
الخاصية نوع الوصف
auth_typ سلسلة اسم موفر الهوية المستخدم بواسطة App Service Authentication.
claims صفيف من الكائنات صفيف من الكائنات التي تمثل المطالبات المتاحة. يحتوي كل كائن على typ وخصائص val .
typ سلسلة اسم المطالبة. قد يكون هذا خاضعا لتعيين المطالبات الافتراضية وقد يختلف عن المطالبة المقابلة المضمنة في رمز مميز.
val سلسلة قيمة المطالبة.
name_typ سلسلة نوع المطالبة بالاسم، وهو عادة URI يوفر معلومات النظام حول المطالبة name إذا تم تعريفها.
role_typ سلسلة نوع مطالبة الدور، وهو عادة URI يوفر معلومات مخطط حول المطالبة role إذا تم تعريف واحد.

لمعالجة هذا العنوان، سيحتاج تطبيقك إلى فك تشفير الحمولة والتكرار من خلال claims الصفيف للعثور على مطالبات الاهتمام. قد يكون من الملائم تحويلها إلى تمثيل يستخدمه إطار عمل لغة التطبيق. فيما يلي مثال على هذه العملية في 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 });
        }

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

بدائل خاصة لإطار العمل

بالنسبة لتطبيقات ASP.NET 4.6، يقوم App Service بتعبئة ClaimsPrincipal.Current بمطالبات المستخدم المصادق عليها، حتى تتمكن من اتباع نمط التعليمات البرمجية ‎.NET القياسي، بما في ذلك السمة [Authorize]. وبالمثل، بالنسبة لتطبيقات PHP، تملأ App Service المتغير _SERVER['REMOTE_USER']. بالنسبة لتطبيقات Java، يمكن الوصول إلى المطالبات من Tomcat servlet.

بالنسبة إلى Azure Functions، ClaimsPrincipal.Current لا يتم ملؤها للتعليمات البرمجية .NET، ولكن لا يزال بإمكانك العثور على مطالبات المستخدم في عناوين الطلب، أو الحصول على ClaimsPrincipal الكائن من سياق الطلب أو حتى من خلال معلمة ربط. لمزيد من المعلومات، راجع العمل مع هويات العميل في Azure Functions.

بالنسبة لـ ‎.NET Core، يدعم Microsoft.Identity.Web ملء المستخدم الحالي بمصادقة App Service. لمعرفة المزيد، يمكنك قراءة ذلك على موقع ويكي Microsoft.Identity.Web، أو الاطلاع عليه موضحاً في هذا البرنامج التعليمي لتطبيق ويب يصل إلى Microsoft Graph.

إشعار

لكي يعمل تعيين المطالبات، يجب تمكين مخزن الرمز المميز.

الوصول إلى مطالبات المستخدم باستخدام واجهة برمجة التطبيقات

إذا تم تمكين مخزن الرمز المميز لتطبيقك، يمكنك أيضا الحصول على تفاصيل أخرى حول المستخدم المصادق عليه عن طريق استدعاء /.auth/me.

الخطوات التالية