البرنامج التعليمي: مصادقة التدفق من App Service من خلال واجهة برمجة التطبيقات الخلفية إلى Microsoft Graph

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

في هذا البرنامج التعليمي، تتعلم كيفية:

  • تكوين تطبيق المصادقة الخلفي لتوفير رمز مميز محدد النطاق لخدمة Azure المتلقية للمعلومات
  • استخدم تعليمة JavaScript البرمجية لتبادل رمز الوصول المميز للمستخدم الذي سجل الدخول لرمز مميز جديد لخدمة انتقال البيانات من الخادم.
  • استخدم تعليمة JavaScript البرمجية للوصول إلى خدمة انتقال البيانات من الخادم.

المتطلبات الأساسية

أكمل البرنامج التعليمي السابق، الوصول إلى Microsoft Graph من تطبيق JavaScript آمن كمستخدم، قبل بدء هذا البرنامج التعليمي ولكن لا تقم بإزالة الموارد في نهاية البرنامج التعليمي. يفترض هذا البرنامج التعليمي أن لديك خدمتي التطبيقات وتطبيقات المصادقة المقابلة.

استخدم البرنامج التعليمي السابق Azure Cloud Shell كواجهة ل Azure CLI. يستمر هذا البرنامج التعليمي في هذا الاستخدام.

البنية

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

Architectural image of App Service connecting to App Service connecting to Microsoft Graph on behalf of a signed-in user.

تدفق المصادقة للمستخدم للحصول على معلومات Microsoft Graph في هذه البنية:

البرنامج التعليمي السابق الذي تم تغطيته:

  1. تسجيل دخول المستخدم إلى خدمة تطبيق الواجهة الأمامية التي تم تكوينها لاستخدام Active Directory كموفر الهوية.
  2. تمرر خدمة تطبيق الواجهة الأمامية الرمز المميز للمستخدم إلى خدمة تطبيق الواجهة الخلفية.
  3. يتم تأمين تطبيق الواجهة الخلفية للسماح للواجهة الأمامية بإجراء طلب واجهة برمجة التطبيقات. يحتوي الرمز المميز للوصول للمستخدم على جمهور لواجهة برمجة التطبيقات الخلفية ونطاق user_impersonation.
  4. يحتوي تسجيل تطبيق الواجهة الخلفية بالفعل على Microsoft Graph مع النطاق User.Read. تتم إضافة هذا بشكل افتراضي إلى جميع تسجيلات التطبيق.
  5. في نهاية البرنامج التعليمي السابق، تم إرجاع ملف تعريف مزيف إلى تطبيق الواجهة الأمامية لأن Graph لم يكن متصلا.

يوسع هذا البرنامج التعليمي البنية:

  1. منح موافقة المسؤول لتجاوز شاشة موافقة المستخدم للتطبيق الخلفي.
  2. قم بتغيير رمز التطبيق لتحويل رمز الوصول المرسل من تطبيق الواجهة الأمامية إلى رمز مميز للوصول مع الإذن المطلوب ل Microsoft Graph.
  3. قم بتوفير التعليمات البرمجية للحصول على رمز تبادل تطبيق خلفي لرمز مميز جديد مع نطاق خدمة Azure المتلقين للمعلومات مثل Microsoft Graph.
  4. قم بتوفير التعليمات البرمجية لجعل تطبيق الواجهة الخلفية يستخدم رمزا مميزا جديدا للوصول إلى خدمة انتقال البيانات من الخادم كمستخدم المصادقة الحالي.
  5. إعادة توزيع تطبيق الواجهة الخلفية باستخدام az webapp up.
  6. في نهاية هذا البرنامج التعليمي، يتم إرجاع ملف تعريف حقيقي إلى تطبيق الواجهة الأمامية لأن Graph متصل.

هذا البرنامج التعليمي لا:

  • تغيير تطبيق الواجهة الأمامية من البرنامج التعليمي السابق.
  • قم بتغيير إذن نطاق تطبيق المصادقة الخلفي لأنه User.Read تتم إضافته افتراضيا إلى جميع تطبيقات المصادقة.

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

في هذا البرنامج التعليمي، لقراءة ملف تعريف المستخدم من Microsoft Graph، يحتاج التطبيق الخلفي إلى استبدال رمز وصول المستخدم الذي سجل الدخول برمز وصول جديد مع الأذونات المطلوبة ل Microsoft Graph. نظرا لأن المستخدم غير متصل مباشرة بتطبيق الواجهة الخلفية، فلا يمكنه الوصول إلى شاشة الموافقة بشكل تفاعلي. يجب حل هذه المشكلة عن طريق تكوين تسجيل التطبيق الخلفي في معرف Microsoft Entra لمنح موافقة المسؤول. هذا تغيير في الإعداد يتم عادة بواسطة مسؤول Active Directory.

  1. افتح مدخل Microsoft Azure وابحث عن بحثك عن خدمة التطبيقات الخلفية.

  2. ابحث عن قسم الإعدادات -> المصادقة.

  3. حدد موفر الهوية للانتقال إلى تطبيق المصادقة.

  4. في تطبيق المصادقة، حدد إدارة -> أذونات واجهة برمجة التطبيقات.

  5. حدد منح موافقة المسؤول للدليل الافتراضي.

    Screenshot of Azure portal authentication app with admin consent button highlighted.

  6. في النافذة المنبثقة، حدد نعم لتأكيد الموافقة.

  7. تحقق من أن عمود الحالة يقول Granted for Default Directory. باستخدام هذا الإعداد، لم يعد التطبيق الخلفي مطلوبا لعرض شاشة الموافقة للمستخدم الذي سجل الدخول ويمكنه طلب رمز مميز للوصول مباشرة. المستخدم الذي قام بتسجيل الدخول لديه حق الوصول إلى User.Read إعداد النطاق لأن هذا هو النطاق الافتراضي الذي يتم إنشاء تسجيل التطبيق به.

    Screenshot of Azure portal authentication app with admin consent granted in status column.

2. تثبيت حزم npm

في البرنامج التعليمي السابق، لم يكن تطبيق الواجهة الخلفية بحاجة إلى أي حزم npm للمصادقة لأنه تم توفير المصادقة الوحيدة عن طريق تكوين موفر الهوية في مدخل Microsoft Azure. في هذا البرنامج التعليمي، يجب استبدال رمز وصول المستخدم الذي سجل الدخول لواجهة برمجة التطبيقات الخلفية برمز مميز للوصول مع Microsoft Graph في نطاقه. اكتمل هذا التبادل مع مكتبتين لأن هذا التبادل لا يستخدم مصادقة App Service بعد الآن، ولكن معرف Microsoft Entra وMSAL.js مباشرة.

  1. افتح Azure Cloud Shell وغير إلى تطبيق الواجهة الخلفية للدليل النموذجي:

    cd js-e2e-web-app-easy-auth-app-to-app/backend
    
  2. تثبيت حزمة Azure MSAL npm:

    npm install @azure/msal-node
    
  3. تثبيت حزمة Microsoft Graph npm:

    npm install @microsoft/microsoft-graph-client
    

3. إضافة تعليمة برمجية لتبادل الرمز المميز الحالي لرمز Microsoft Graph المميز

يتم توفير التعليمات البرمجية المصدر لإكمال هذه الخطوة لك. استخدم الخطوات التالية لتضمينه.

  1. افتح الملف ./src/server.js.

  2. إلغاء التعليق على التبعية التالية في أعلى الملف:

    import { getGraphProfile } from './with-graph/graph';
    
  3. في نفس الملف، قم بإلغاء التعليق على graphProfile المتغير:

    let graphProfile={};
    
  4. في نفس الملف، قم بإلغاء التعليق على الأسطر التالية getGraphProfile في get-profile المسار للحصول على ملف التعريف من Microsoft Graph:

    // where did the profile come from
    profileFromGraph=true;
    
    // get the profile from Microsoft Graph
    graphProfile = await getGraphProfile(accessToken);
    
    // log the profile for debugging
    console.log(`profile: ${JSON.stringify(graphProfile)}`);
    
  5. احفظ التغييرات: Ctrl + s.

  6. إعادة نشر تطبيق الواجهة الخلفية:

    az webapp up --resource-group myAuthResourceGroup --name <back-end-app-name> 
    
    

4. فحص التعليمات البرمجية الخلفية لتبادل الرمز المميز لواجهة برمجة التطبيقات الخلفية للرمز المميز ل Microsoft Graph

لتغيير الرمز المميز لجمهور واجهة برمجة التطبيقات الخلفية للرمز المميز ل Microsoft Graph، يحتاج تطبيق الواجهة الخلفية إلى العثور على معرف المستأجر واستخدامه كجزء من كائن تكوين MSAL.js. نظرا لأن تطبيق الواجهة الخلفية الذي تم تكوينه مع Microsoft كموفر هوية، فإن معرف المستأجر والعديد من القيم المطلوبة الأخرى موجودة بالفعل في إعدادات تطبيق App service.

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

فحص التعليمات البرمجية للحصول على معرف المستأجر

  1. افتح الملف ./backend/src/with-graph/auth.js.

  2. راجع الدالة getTenantId() .

    export function getTenantId() {
    
        const openIdIssuer = process.env.WEBSITE_AUTH_OPENID_ISSUER;
        const backendAppTenantId = openIdIssuer.replace(/https:\/\/sts\.windows\.net\/(.{1,36})\/v2\.0/gm, '$1');
    
        return backendAppTenantId;
    }
    
  3. تحصل هذه الدالة على معرف المستأجر الحالي من WEBSITE_AUTH_OPENID_ISSUER متغير البيئة. يتم تحليل المعرف خارج المتغير بتعبير عادي.

فحص التعليمات البرمجية للحصول على رمز Graph المميز باستخدام MSAL.js

  1. لا يزال في ./backend/src/with-graph/auth.js الملف، راجع الدالة getGraphToken() .

  2. أنشئ كائن تكوين MSAL.js، واستخدم تكوين MSAL لإنشاء clientCredentialAuthority. تكوين طلب نيابة عن. ثم استخدم acquireTokenOnBehalfOf لتبادل الرمز المميز للوصول إلى واجهة برمجة التطبيقات الخلفية رموز الوصول إلى Graph.

    // ./backend/src/auth.js
    // Exchange current bearerToken for Graph API token
    // Env vars were set by App Service
    export async function getGraphToken(backEndAccessToken) {
    
        const config = {
            // MSAL configuration
            auth: {
                // the backend's authentication CLIENT ID 
                clientId: process.env.WEBSITE_AUTH_CLIENT_ID,
                // the backend's authentication CLIENT SECRET 
                clientSecret: process.env.MICROSOFT_PROVIDER_AUTHENTICATION_SECRET,
                // OAuth 2.0 authorization endpoint (v2)
                // should be: https://login.microsoftonline.com/BACKEND-TENANT-ID
                authority: `https://login.microsoftonline.com/${getTenantId()}`
            },
            // used for debugging
            system: {
                loggerOptions: {
                    loggerCallback(loglevel, message, containsPii) {
                        console.log(message);
                    },
                    piiLoggingEnabled: true,
                    logLevel: MSAL.LogLevel.Verbose,
                }
            }
        };
    
        const clientCredentialAuthority = new MSAL.ConfidentialClientApplication(config);
    
        const oboRequest = {
            oboAssertion: backEndAccessToken,
            // this scope must already exist on the backend authentication app registration 
            // and visible in resources.azure.com backend app auth config
            scopes: ["https://graph.microsoft.com/.default"]
        }
    
        // This example has App service validate token in runtime
        // from headers that can't be set externally
    
        // If you aren't using App service's authentication, 
        // you must validate your access token yourself
        // before calling this code
        try {
            const { accessToken } = await clientCredentialAuthority.acquireTokenOnBehalfOf(oboRequest);
            return accessToken;
        } catch (error) {
            console.log(`getGraphToken:error.type = ${error.type}  ${error.message}`);
        }
    }
    

5. فحص التعليمات البرمجية الخلفية للوصول إلى Microsoft Graph باستخدام الرمز المميز الجديد

للوصول إلى Microsoft Graph كمستخدم سجل الدخول إلى تطبيق الواجهة الأمامية، تتضمن التغييرات ما يلي:

  • تكوين تسجيل تطبيق Active Directory مع إذن واجهة برمجة التطبيقات لخدمة انتقال البيانات من الخادم، Microsoft Graph، مع النطاق الضروري ل User.Read.
  • منح موافقة المسؤول لتجاوز شاشة موافقة المستخدم للتطبيق الخلفي.
  • قم بتغيير رمز التطبيق لتحويل رمز الوصول المرسل من تطبيق الواجهة الأمامية إلى رمز وصول مع الإذن المطلوب لخدمة انتقال البيانات من الخادم، Microsoft Graph.

الآن بعد أن أصبح الرمز يحتوي على الرمز المميز الصحيح ل Microsoft Graph، استخدمه لإنشاء عميل إلى Microsoft Graph ثم احصل على ملف تعريف المستخدم.

  1. افتح ./backend/src/graph.js

  2. في الدالة getGraphProfile() ، احصل على الرمز المميز، ثم العميل المصادق عليه من الرمز المميز ثم احصل على ملف التعريف.

    // 
    import graph from "@microsoft/microsoft-graph-client";
    import { getGraphToken } from "./auth.js";
    
    // Create client from token with Graph API scope
    export function getAuthenticatedClient(accessToken) {
        const client = graph.Client.init({
            authProvider: (done) => {
                done(null, accessToken);
            }
        });
    
        return client;
    }
    export async function getGraphProfile(accessToken) {
        // exchange current backend token for token with 
        // graph api scope
        const graphToken = await getGraphToken(accessToken);
    
        // use graph token to get Graph client
        const graphClient = getAuthenticatedClient(graphToken);
    
        // get profile of user
        const profile = await graphClient
            .api('/me')
            .get();
    
        return profile;
    }
    

6. اختبار التغييرات التي أجريتها

  1. استخدم موقع ويب للواجهة الأمامية في مستعرض. عنوان URL بتنسيق https://<front-end-app-name>.azurewebsites.net/. قد تحتاج إلى تحديث الرمز المميز الخاص بك إذا انتهت صلاحيته.

  2. حدد Get user's profile. يؤدي ذلك إلى تمرير المصادقة الخاصة بك في الرمز المميز للحامل إلى الخلفية.

  3. تستجيب النهاية الخلفية بملف تعريف Microsoft Graph الحقيقي لحسابك.

    Screenshot of web browser showing frontend application after successfully getting real profile from backend app.

7. تنظيف

في الخطوات السابقة، أنشأت موارد Azure في إحدى مجموعات الموارد.

  1. احذف مجموعة الموارد عن طريق تشغيل الأمر التالي في Cloud Shell. ربما يستغرق الأمر بضع دقائق للتشغيل.

    az group delete --name myAuthResourceGroup
    
  2. استخدم معرف العميل لتطبيقات المصادقة، الذي عثرت عليه مسبقا وقمت بتدوينه في Enable authentication and authorization أقسام تطبيقات الواجهة الخلفية والواجهة الأمامية.

  3. احذف تسجيلات التطبيقات لكل من تطبيقات الواجهة الأمامية والخلفية.

    # delete app - do this for both frontend and backend client ids
    az ad app delete <client-id>
    

الأسئلة المتداولة

تلقيت خطأ 80049217، ماذا يعني ذلك؟

هذا الخطأ، CompactToken parsing failed with error code: 80049217، يعني أن خدمة التطبيق الخلفية غير مصرح لها بإرجاع الرمز المميز ل Microsoft Graph. يحدث هذا الخطأ لأن تسجيل التطبيق يفتقد الإذن User.Read .

تلقيت خطأ AADSTS65001، ماذا يعني ذلك؟

يعني هذا الخطأ، AADSTS65001: The user or administrator has not consented to use the application with ID \<backend-authentication-id>. Send an interactive authorization request for this user and resource، أن تطبيق المصادقة الخلفي لم يتم تكوينه للموافقة مسؤول. نظرا إلى ظهور الخطأ في سجل تطبيق الواجهة الخلفية، لا يمكن لتطبيق الواجهة الأمامية إخبار المستخدم بسبب عدم رؤيته لملف التعريف الخاص به في تطبيق الواجهة الأمامية.

كيف أعمل الاتصال بخدمة Azure مختلفة عند انتقال البيانات من الخادم كمستخدم؟

يوضح هذا البرنامج التعليمي تطبيق API تمت مصادقته على Microsoft Graph، ومع ذلك، يمكن تطبيق نفس الخطوات العامة للوصول إلى أي خدمة Azure نيابة عن المستخدم.

  1. لا يوجد تغيير في تطبيق الواجهة الأمامية. التغييرات فقط على تسجيل تطبيق المصادقة للواجهة الخلفية ورمز مصدر تطبيق الواجهة الخلفية.
  2. تبادل الرمز المميز للمستخدم محدد النطاق لواجهة برمجة التطبيقات الخلفية للحصول على رمز مميز لخدمة انتقال البيانات من الخادم التي تريد الوصول إليها.
  3. استخدم الرمز المميز في SDK لخدمة انتقال البيانات من الخادم لإنشاء العميل.
  4. استخدم عميل انتقال البيانات من الخادم للوصول إلى وظائف الخدمة.

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