استخدام نطاقات OAuth2

يتم الآن عرض مستندات Apigee Edge.
انتقِل إلى مستندات Apigee X.
المعلومات

يناقش هذا الموضوع كيفية استخدام نطاقات OAuth 2.0 على Apigee Edge.

ما هو نطاق OAuth2؟

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

في هذا الموضوع، سنناقش كيفية تعيين النطاقات لرموز الدخول وكيفية تنفيذ Apigee Edge لنطاقات OAuth 2.0. بعد قراءة هذا الموضوع، ستتمكّن من استخدام النطاقات بثقة.

كيف يتم تعيين النطاقات لرموز الدخول؟

عندما ينشئ متصفّح Edge رمز دخول، قد يحدّد نطاقًا لذلك الرمز المميّز. لفهم آلية حدوث ذلك، يجب أولاً أن تكون على دراية بكيانات Apigee Edge هذه: منتجات واجهة برمجة التطبيقات، والمطوّرين، وتطبيقات المطوّرين. للحصول على مقدمة حول النشر، يُرجى الاطّلاع على مقدمة عن النشر. ننصحك بمراجعة هذه المواد إذا كنت بحاجة إلى ذلك قبل المتابعة.

رمز الدخول هو سلسلة طويلة من الأحرف ذات المظهر العشوائي التي تتيح لأداة Edge إمكانية التحقّق من طلبات البيانات الواردة من واجهة برمجة التطبيقات (يمكنك اعتبارها كبديل لبيانات اعتماد اسم المستخدم/كلمة المرور المعتادة). من الناحية الفنية، الرمز المميّز هو مفتاح يشير إلى مجموعة من البيانات الوصفية التي تبدو على النحو التالي:

{
  "issued_at" : "1416962591727",
  "application_name" : "0d3e1d41-a59f-4d74-957e-d4e3275d4781",
  "scope" : "A",
  "status" : "approved",
  "api_product_list" : "[scopecheck1-bs0cSuqS9y]",
  "expires_in" : "1799", //--in seconds
  "developer.email" : "scopecheck1-AdBmANhsag@apigee.com",
  "organization_id" : "0",
  "token_type" : "BearerToken",
  "client_id" : "eTtB7w5lvk3DnOZNGReBlvGvIAeAywun",
  "access_token" : "ODm47ris5AlEty8TDc1itwYPe5MW",
  "organization_name" : "wwitman",
  "refresh_token_expires_in" : "0", //--in seconds
  "refresh_count" : "0"
}

تتضمن البيانات الوصفية للرمز المميّز سلسلة رمز الدخول الفعلي ومعلومات انتهاء الصلاحية وتعريف تطبيق المطوّر ومطوّر البرامج والمنتجات المرتبطة بالرمز المميّز. وستلاحظ أيضًا أنّ البيانات الوصفية تتضمّن كلمة "النطاق" أيضًا.

كيف يحصل الرمز المميّز على نطاقه؟

أول مفتاح لفهم النطاق هو تذكُّر أنّ كل منتج في تطبيق المطوّر لا يمكن أن يتم تحديد أي نطاقات له أو أكثر. يمكن تخصيص هذه النطاقات عند إنشاء المنتج، أو يمكن إضافتها لاحقًا. وتتوفّر هذه العلامات كقائمة أسماء ويتم تضمينها في "البيانات الوصفية" المرتبطة بكل منتج.

عند إنشاء تطبيق مطوِّر وإضافة منتجات إليه، يفحص متصفِّح Edge جميع المنتجات المضمَّنة في تطبيق المطوِّر وينشئ قائمة بجميع النطاقات لهذه المنتجات (قائمة النطاقات الرئيسية أو العالمية للتطبيق، والتي تمثّل اتحادًا لجميع النطاقات المعروفة).

عندما يطلب تطبيق عميل رمز دخول من Apigee Edge، يمكنه اختياريًا تحديد النطاقات التي يريد ربطها بهذا الرمز المميّز. على سبيل المثال، يطلب الطلب التالي النطاق "A". وهذا يعني أنّ العميل يطلب من خادم التفويض (Edge) إنشاء رمز دخول يتضمّن النطاق "A" (يمنح إذن التطبيق لطلب واجهات برمجة التطبيقات التي لها النطاق "A"). يرسل التطبيق طلب POST على النحو التالي:

curl -i -X POST -H Authorization: Basic Mg12YTk2UkEIyIBCrtro1QpIG -H content-type:application/x-www-form-urlencoded http://myorg-test.apigee.net/oauth/token?grant_type=client_credentials&scope=A

ماذا يحدث؟

وعندما يتلقّى Edge هذا الطلب، فإنّه يعرف التطبيق الذي يُجري الطلب ويحدّد تطبيق المطوّر الذي سجّله العميل (يتم ترميز معرّف العميل ومفاتيح سر العميل في عنوان المصادقة الأساسي). بسبب تضمين مَعلمة طلب البحث scope، يجب أن يقرر Edge ما إذا كان أي من منتجات واجهة برمجة التطبيقات المرتبطة بتطبيق المطوّر يتضمّن النطاق "A". وفي حال إجراء ذلك، سيتم إنشاء رمز دخول باستخدام النطاق "أ". هناك طريقة أخرى للتحقّق من ذلك، وهي أنّ مَعلمة طلب البحث للنطاق هي نوع من الفلاتر. إذا تعرّف تطبيق المطوّر على النطاقات "أ" و"ب" و"س"، وكانت معلَمة طلب البحث تحدّد "scope=X Y Z"، حينئذٍ سيتم تخصيص النطاق "X" فقط للرمز المميّز.

ماذا لو لم يرفق العميل معلَمة نطاق؟ في هذه الحالة، ينشئ Edge رمزًا مميزًا يتضمّن جميع النطاقات التي يتعرّف عليها تطبيق المطوِّر. من المهم معرفة أنّ السلوك التلقائي هو عرض رمز دخول يتضمّن اتحاد جميع النطاقات لكل المنتجات المضمّنة في تطبيق المطوِّر.

إذا لم تحدّد أي من المنتجات المرتبطة بتطبيق المطوّر نطاقات، وكان للرمز المميّز نطاق، لن تنجح المكالمات التي يتم إجراؤها باستخدام هذا الرمز المميّز.

لنفترض أنّ أحد تطبيقات المطوّرين يتعرّف على هذه النطاقات: أ ب ج. هذه هي القائمة الرئيسية للنطاقات الخاصة بالتطبيق. قد يكون هناك منتج واحد في التطبيق يضم النطاقَين "أ" و"ب"، بينما يتضمّن المنتج الثاني النطاقَين "ج" و"د"، أو أي مجموعة من المنتجات. إذا لم يحدّد العميل معلَمة scope (أو إذا تم تحديد معلَمة نطاق بدون قيمة)، سيتم منح الرمز المميّز لجميع النطاقات الأربعة: "أ" و"ب" و"ج" و"د". ونذكر مرة أخرى أن الرمز المميز يتلقى مجموعة من النطاقات التي تمثل اتحاد جميع النطاقات التي يتعرف عليها تطبيق المطوِّر.

هناك حالة أخرى يكون السلوك التلقائي فيها هو عرض رمز دخول مع جميع النطاقات المعروفة، وذلك عندما لا تحدّد سياسة GenerateAccessToken (سياسة Apigee Edge التي تنشئ رموز الدخول) عنصر <Scope>. على سبيل المثال، إليك سياسة GenerateAccessToken في سياسة <Scope> يتم تحديدها. في حال عدم توفّر العنصر <Scope> (أو إذا كان متوفرًا ولكنّه فارغ)، يتم تنفيذ السلوك التلقائي.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<OAuthV2 async="false" continueOnError="false" enabled="true" name="OAuthV2-GenerateAccessToken">
    <DisplayName>OAuthV2 - Generate Access Token</DisplayName>
    <Attributes>
      <Attribute name='hello' ref='system.time' display='false'>value1</Attribute>
    </Attributes>
    <Scope>request.queryparam.scope</Scope> 
    <GrantType>request.formparam.grant_type</GrantType>
    <ExternalAuthorization>false</ExternalAuthorization>
    <Operation>GenerateAccessToken</Operation>
    <SupportedGrantTypes>
      <GrantType>client_credentials</GrantType>
    </SupportedGrantTypes>
  <GenerateResponse enabled="true"/>
</OAuthV2>

كيف يتم فرض النطاقات؟

تذكَّر أولاً أنّه في Apigee Edge، يتم التحقّق من رموز الدخول باستخدام سياسة OAuthV2 (يتم وضعها عادةً في بداية مسار الخادم الوكيل). يجب أن تتضمّن السياسة عملية CheckAccessToken المُحددة. في ما يلي بعض المعلومات عن هذه السياسة:

<OAuthV2 async="false" continueOnError="false" enabled="true" name="OAuthV2-VerifyAccessTokenA">
    <DisplayName>Verify OAuth v2.0 Access Token</DisplayName>
    <ExternalAuthorization>false</ExternalAuthorization>
    <Operation>VerifyAccessToken</Operation>
    <Scope>A</Scope> <!-- Optional: space-separated list of scope names. -->
    <GenerateResponse enabled="true"/>
</OAuthV2>

يُرجى ملاحظة العنصر <Scope>. ويتم استخدامه لتحديد النطاقات التي ستقبلها السياسة.

في هذا المثال، لن تنجح السياسة إلا إذا كان رمز الدخول يتضمن النطاق "أ". في حال حذف عنصر <Scope> هذا أو إذا لم يكن له أي قيمة، ستتجاهل السياسة نطاق رمز الدخول.

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

لنفترض أنّ واجهة برمجة التطبيقات تتضمّن مسارًا محدّدًا لنقطة النهاية /resourceA:

<Flow name="resourceA">
            <Condition>(proxy.pathsuffix MatchesPath "/resourceA") and (request.verb = "GET")</Condition>
            <Description>Get a resource A</Description>
            <Request>
                <Step>
                    <Name>OAuthV2-VerifyAccessTokenA</Name>
                </Step>
            </Request>
            <Response>
                <Step>
                    <Name>AssignMessage-CreateResponse</Name>
                </Step>
            </Response>
        </Flow>

عند بدء هذا المسار (يأتي الطلب مع /resourceA في لاحقة المسار)، يتم استدعاء سياسة OAuthV2-CheckAccessTokenA على الفور. تتحقّق هذه السياسة من صلاحية رمز الدخول، كما تبحث عن النطاقات المتوافقة مع الرمز المميّز. في حال ضبط السياسة على النحو التالي، من خلال <Scope>A</Scope>، لن تنجح السياسة إلا إذا كان رمز الدخول يتضمّن النطاق "A". وإلا، ستظهر رسالة خطأ.

<OAuthV2 async="false" continueOnError="false" enabled="true" name="OAuthV2-VerifyAccessTokenA">
    <DisplayName>Verify OAuth v2.0 Access Token</DisplayName>
    <ExternalAuthorization>false</ExternalAuthorization>
    <Operation>VerifyAccessToken</Operation>
    <Scope>A</Scope>
    <GenerateResponse enabled="true"/>
</OAuthV2>

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

أمثلة على الرموز البرمجية

أخيرًا، لنلقِ نظرة على بعض أمثلة طلبات البيانات من واجهة برمجة التطبيقات لتوضيح كيفية تلقّي الرموز المميّزة للنطاقات وطريقة فرض هذه النطاقات.

الحالة التلقائية

لنفترض أن لديك تطبيق مطوّر يضم منتجات، وأن اتحاد نطاقات هذه المنتجات هو: "أ" و"ب" و"ج". يطلب طلب البيانات من واجهة برمجة التطبيقات هذا رمز دخول، ولكنه لا يحدّد مَعلمة طلب البحث للنطاق.

curl -X POST -H content-type:application/x-www-form-urlencoded http://wwitman-test.apigee.net/scopecheck1/token?grant_type=client_credentials

في هذه الحالة، سيتم منح الرمز المميز الذي تم إنشاؤه النطاقات "أ"، و"ب"، و"ج" (السلوك التلقائي). ستظهر البيانات الوصفية للرمز المميّز على النحو التالي:

{
  "issued_at" : "1417016208588",
  "application_name" : "eb1a0333-5775-4116-9eb2-c36075ddc360",
  "scope" : "A B C",
  "status" : "approved",
  "api_product_list" : "[scopecheck1-yEgQbQqjRR]",
  "expires_in" : "1799", //--in seconds
  "developer.email" : "scopecheck1-yxiuHuZcDW@apigee.com",
  "organization_id" : "0",
  "token_type" : "BearerToken",
  "client_id" : "atGFvl3jgA0pJd05rXKHeNAC69naDmpW",
  "access_token" : "MveXpj4UYXol38thNoJYIa8fBGlI",
  "organization_name" : "wwitman",
  "refresh_token_expires_in" : "0", //--in seconds
  "refresh_count" : "0"
}

لنفترض الآن أن لديك نقطة نهاية لواجهة برمجة تطبيقات تشتمل على النطاق "أ" (أي أنها تطلب النطاق "أ" للتحقق من الوصول ). في ما يلي سياسة CheckAccessToken:

<OAuthV2 async="false" continueOnError="false" enabled="true" name="OAuthV2-VerifyAccessTokenA">
    <DisplayName>Verify OAuth v2.0 Access Token</DisplayName>
    <ExternalAuthorization>false</ExternalAuthorization>
    <Operation>VerifyAccessToken</Operation>
    <Scope>A</Scope>
    <GenerateResponse enabled="true"/>
</OAuthV2>

في ما يلي نموذج لطلب الاتصال ونقطة النهاية التي تفرض النطاق "أ":

curl -X GET -H Authorization: Bearer MveXpj4UYXol38thNoJYIa8fBGlI http://wwitman-test.apigee.net/scopecheck1/resourceA 

نجح طلب استدعاء GET هذا:

 {
   "hello" : "Tue, 25 Nov 2014 01:35:53 UTC"
 }

ينجح هذا الإجراء لأنّ سياسة التحقّق من الوصول التي يتم تشغيلها عند استدعاء نقطة النهاية تتطلّب النطاق "أ"، وتم منح رمز الدخول النطاقات "أ" و"ب" و"ج"، وهو السلوك التلقائي.

حالة الفلترة

لنفترض أن لديك تطبيق مطوّر برامج يحتوي على منتجات تتضمّن النطاقات "أ" و"ب" و"ج" و"س". عليك طلب رمز دخول مميز وتضمين معلمة طلب البحث scope على النحو التالي:

curl -i -X POST -H content-type:application/x-www-form-urlencoded 'http://myorg-test.apigee.net/oauth/token?grant_type=client_credentials&scope=A X'

في هذه الحالة، سيتم تخصيص النطاقَين A وX للرمز المميّز الذي تم إنشاؤه، لأنّ كلاً من A وX نطاقان صالحان. تذكر أن تطبيق المطور يتعرف على النطاقات "أ" و"ب" و"ج" و"س". في هذه الحالة، ستتم فلترة قائمة منتجات واجهة برمجة التطبيقات استنادًا إلى هذه النطاقات. إذا كان المنتج يتضمّن النطاق "أ" أو "س"، يمكنك ضبط نقاط نهاية واجهة برمجة التطبيقات التي ستفرض هذه النطاقات. إذا لم يكن المنتج يتضمّن النطاق "أ" أو "س" (إذا حصل على النطاق "ب" و"ج" و"ع")، لا يمكن استدعاء واجهات برمجة التطبيقات التي تفرض النطاقَين "أ" أو "س" باستخدام الرمز المميّز.

عند استدعاء واجهة برمجة التطبيقات باستخدام الرمز المميّز الجديد:

curl -X GET -H Authorization: Bearer Rkmqo2UkEIyIBCrtro1QpIG http://wwitman-test.apigee.net/scopecheck1/resourceX

يتم التحقّق من رمز الدخول من خلال الخادم الوكيل لواجهة برمجة التطبيقات. مثال:

<OAuthV2 async="false" continueOnError="false" enabled="true" name="OAuthV2-VerifyAccessTokenX">
    <DisplayName>Verify OAuth v2.0 Access Token</DisplayName>
    <ExternalAuthorization>false</ExternalAuthorization>
    <Operation>VerifyAccessToken</Operation>
    <Scope>A X</Scope>
    <GenerateResponse enabled="true"/>
</OAuthV2>

تنجح عمليات تشغيل استدعاء GET وتعرض استجابة. مثال:

 {
   "hello" : "Tue, 25 Nov 2014 01:35:53 UTC"
 }
 

ينجح هذا الإجراء لأنّ سياسة التحقّق من الدخول تتطلب النطاق "أ" أو "س"، وأنّ رمز الدخول يتضمّن النطاقَين "أ" و"س". وبالطبع، إذا تم ضبط العنصر <Scope> على "B"، سيتعذّر إتمام هذا الطلب.

ملخّص

من المهم فهم كيفية تعامل Apigee Edge مع نطاقات OAuth 2.0. في ما يلي بعض النقاط الرئيسية:

  • "يتعرّف" تطبيق مطوّر البرامج على اتحاد جميع النطاقات المحددة لجميع منتجاته.
  • عندما يطلب تطبيق رمز دخول مميّزًا، تكون لديه فرصة تحديد النطاقات التي يريد الحصول عليها. يرجع الأمر إلى Apigee Edge (خادم التفويض) لتحديد النطاقات التي سيخصّصها التطبيق لرمز الدخول استنادًا إلى (أ) النطاقات المطلوبة و(ب) النطاقات التي يتعرّف عليها تطبيق المطوّر.
  • إذا لم يتم ضبط Apigee Edge للتحقّق من النطاق (أي أنّ العنصر <Scope> غير متوفّر في سياسة CheckAccessToken أو أنّه فارغ)، سينجح طلب البيانات من واجهة برمجة التطبيقات ما دام النطاق المضمّن في رمز الدخول يتطابق مع أحد النطاقات التي تعرّف عليها تطبيق المطوّر المسجَّل (أحد النطاقات ضِمن قائمة النطاقات "الرئيسية" للتطبيق).
  • إذا لم يكن رمز الدخول يتضمّن أي نطاقات مرتبطة به، لن ينجح هذا الرمز إلا في الحالات التي لا يراعي فيها Edge النطاق (العنصر <Scope> غير متوفّر في سياسة التحقّق من الوصول أو إذا كان فارغًا).