کار با دامنه های OAuth2

شما در حال مشاهده اسناد Apigee Edge هستید.
به مستندات Apigee X بروید .
اطلاعات

این موضوع نحوه استفاده از دامنه های OAuth 2.0 در Apigee Edge را مورد بحث قرار می دهد.

محدوده OAuth2 چیست؟

دامنه های OAuth 2.0 راهی برای محدود کردن میزان دسترسی اعطا شده به یک نشانه دسترسی فراهم می کند. به عنوان مثال، یک نشانه دسترسی صادر شده برای یک برنامه مشتری ممکن است به منابع محافظت شده دسترسی READ و WRITE یا فقط دسترسی READ داده شود. شما می توانید API های خود را برای اعمال هر محدوده یا ترکیبی از حوزه های مورد نظر خود پیاده سازی کنید. بنابراین، اگر یک کلاینت توکنی دریافت کند که دامنه READ دارد و سعی کند یک نقطه پایانی API را که نیاز به دسترسی WRITE دارد فراخوانی کند، تماس با شکست مواجه خواهد شد.

در این مبحث، نحوه تخصیص دامنه ها به توکن ها و نحوه اعمال Apigee Edge محدوده های OAuth 2.0 را مورد بحث قرار خواهیم داد. پس از مطالعه این مبحث، می توانید با اطمینان از اسکوپ ها استفاده کنید.

چگونه دامنه ها به توکن های دسترسی اختصاص داده می شوند؟

هنگامی که Edge یک نشانه دسترسی تولید می کند، ممکن است یک محدوده به آن توکن اختصاص دهد. برای درک اینکه چگونه این اتفاق می افتد، ابتدا باید با این موجودیت های Apigee Edge آشنا شوید: محصولات API، توسعه دهندگان و برنامه های توسعه دهنده. برای مقدمه، به مقدمه انتشار مراجعه کنید. توصیه می کنیم در صورت نیاز قبل از ادامه، این مطالب را مرور کنید.

یک نشانه دسترسی یک رشته طولانی از کاراکترهای تصادفی است که به Edge اجازه می‌دهد تا درخواست‌های API ورودی را تأیید کند (آن را به عنوان یک پایه برای اعتبار نام کاربری/گذرواژه معمولی در نظر بگیرید). از نظر فنی، توکن کلیدی است که به مجموعه‌ای از ابرداده‌ها اشاره دارد که به شکل زیر است:

{
  "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"
}

فراداده توکن شامل رشته توکن دسترسی واقعی، اطلاعات انقضا، شناسایی برنامه توسعه دهنده، توسعه دهنده و محصولات مرتبط با توکن است. همچنین متوجه خواهید شد که ابرداده همچنین شامل "scope" است.

توکن چگونه دامنه خود را بدست می آورد؟

اولین کلید برای درک دامنه این است که به یاد داشته باشید که هر محصول در یک برنامه توسعه دهنده می تواند صفر یا بیشتر محدوده به آن اختصاص داده شود. این محدوده ها را می توان در هنگام ایجاد محصول اختصاص داد، یا می توان آنها را بعدا اضافه کرد. آنها به عنوان لیستی از نام ها وجود دارند و در "فراداده" مرتبط با هر محصول گنجانده شده اند.

وقتی یک برنامه توسعه‌دهنده ایجاد می‌کنید و محصولاتی را به آن اضافه می‌کنید، Edge به همه محصولات موجود در برنامه توسعه‌دهنده نگاه می‌کند و فهرستی از همه حوزه‌های آن محصولات ایجاد می‌کند (مستر برنامه یا فهرست دامنه جهانی - اتحادیه‌ای از همه شناخته‌شده‌ها دامنه ها).

هنگامی که یک برنامه مشتری از Apigee Edge توکن دسترسی درخواست می‌کند، می‌تواند به صورت اختیاری مشخص کند که می‌خواهد چه محدوده‌هایی را با آن توکن مرتبط کند. به عنوان مثال، درخواست زیر محدوده "A" را می خواهد. یعنی کلاینت از سرور مجوز (Edge) می‌خواهد که یک نشانه دسترسی با دامنه "A" ایجاد کند (به برنامه اجازه می‌دهد تا APIهایی را که محدوده "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 query گنجانده شده است، Edge باید تصمیم بگیرد که آیا هر یک از محصولات API مرتبط با برنامه توسعه دهنده دارای محدوده "A" هستند یا خیر. اگر این کار را انجام دهند، یک نشانه دسترسی با محدوده "A" تولید می شود. راه دیگری برای بررسی این موضوع این است که پارامتر scope query نوعی فیلتر است. اگر برنامه توسعه‌دهنده دامنه‌های "A، B، X" را تشخیص دهد و پارامتر پرس و جو "scope=XYZ" را مشخص کند، تنها محدوده "X" به نشانه اختصاص داده می‌شود.

اگر مشتری یک پارامتر scope را ضمیمه نکند چه؟ در این مورد، Edge یک توکن تولید می‌کند که شامل تمام حوزه‌های شناسایی شده توسط برنامه توسعه‌دهنده است. درک این نکته مهم است که رفتار پیش‌فرض، بازگرداندن یک نشانه دسترسی است که شامل اتحاد همه دامنه‌ها برای همه محصولات موجود در برنامه توسعه‌دهنده است.

اگر هیچ یک از محصولات مرتبط با برنامه توسعه‌دهنده محدوده‌ای را مشخص نکند، و یک توکن دارای محدوده باشد، تماس‌های انجام‌شده با آن توکن ناموفق خواهند بود.

فرض کنید یک برنامه توسعه‌دهنده این حوزه‌ها را تشخیص می‌دهد: ABC D. این فهرست اصلی دامنه‌های برنامه است. ممکن است یک محصول در برنامه دارای محدوده A و B باشد و محصول دوم دارای محدوده C و D یا هر ترکیب دیگری باشد. اگر مشتری یک پارامتر scope را مشخص نکند (یا اگر پارامتر scope را بدون مقدار مشخص کند) به نشانه هر چهار محدوده A، B، C و D داده می شود. باز هم، نشانه مجموعه ای از دامنه ها را دریافت می کند که عبارتند از اتحاد همه حوزه های شناسایی شده توسط برنامه توسعه دهنده.

یک مورد دیگر وجود دارد که رفتار پیش‌فرض این است که یک نشانه دسترسی با تمام محدوده‌های شناسایی شده را برگرداند، و آن زمانی است که خط‌مشی 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 (معمولاً در همان ابتدای جریان پروکسی قرار می‌گیرند) تأیید می‌شوند. این خط مشی باید عملیات VerifyAccessToken را مشخص کرده باشد. بیایید به این سیاست نگاه کنیم:

<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> توجه کنید. برای مشخص کردن این که خط مشی چه حوزه هایی را می پذیرد استفاده می شود.

در این مثال، سیاست تنها در صورتی موفق خواهد شد که رمز دسترسی شامل محدوده "A" باشد. اگر این عنصر <Scope> حذف شود یا هیچ مقداری نداشته باشد، این خط مشی محدوده نشانه دسترسی را نادیده می گیرد.

اکنون، با قابلیت اعتبارسنجی توکن‌های دسترسی بر اساس محدوده، می‌توانید APIهای خود را برای اعمال دامنه‌های خاص طراحی کنید. شما این کار را با طراحی جریان‌های سفارشی با خط‌مشی‌های VerifyAccessToken مرتبط با آن‌ها انجام می‌دهید.

فرض کنید API شما یک جریان تعریف شده برای نقطه پایانی /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-VerifyAccessTokenA بلافاصله فراخوانی می شود. این خط‌مشی تأیید می‌کند که نشانه دسترسی معتبر است و به نظر می‌رسد تا ببیند که این نشانه از چه حوزه‌ای پشتیبانی می‌کند. اگر این خط‌مشی مانند مثال زیر پیکربندی شود، با <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>

به طور خلاصه، توسعه دهندگان API مسئول طراحی اجرای دامنه در API های خود هستند. آن‌ها این کار را با ایجاد جریان‌های سفارشی برای رسیدگی به حوزه‌های خاص، و پیوست کردن سیاست‌های VerifyAccessToken برای اجرای آن حوزه‌ها انجام می‌دهند.

نمونه های کد

در نهایت، اجازه دهید نگاهی به برخی از فراخوان‌های API مثال بیندازیم تا به نشان دادن نحوه دریافت توکن‌ها و نحوه اعمال دامنه کمک کنیم.

مورد پیش فرض

فرض کنید یک برنامه توسعه‌دهنده با محصولات دارید، و اتحادیه حوزه‌های آن محصولات عبارتند از: A، B، و C. این فراخوانی API یک نشانه دسترسی درخواست می‌کند، اما یک پارامتر پرس و جوی محدوده را مشخص نمی‌کند.

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

در این حالت، توکن تولید شده دارای دامنه های A، B و C (رفتار پیش فرض) خواهد بود. ابرداده توکن چیزی شبیه به این خواهد بود:

{
  "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"
}

حال، فرض کنید یک نقطه پایانی API دارید که دارای محدوده "A" است (یعنی VerifyAccessToken به محدوده "A" نیاز دارد). در اینجا خط مشی VerifyAccessToken آمده است:

<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>

در اینجا یک نمونه تماس و نقطه پایانی وجود دارد که محدوده A را اعمال می کند:

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

این تماس GET موفق شد:

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

موفقیت آمیز است زیرا خط مشی VerifyAccessToken که هنگام فراخوانی نقطه پایانی راه‌اندازی می‌شود، به محدوده A نیاز دارد، و به نشانه دسترسی، دامنه‌های A، B و C داده شده است - رفتار پیش‌فرض.

کیس فیلتر

فرض کنید یک برنامه توسعه‌دهنده با محصولاتی دارید که دارای محدوده‌های A، B، C و X هستند. شما یک نشانه دسترسی درخواست می‌کنید و پارامتر scope query را در آن قرار می‌دهید، مانند این:

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 یک محدوده معتبر هستند. به یاد داشته باشید که برنامه توسعه‌دهنده محدوده‌های A، B، C و X را می‌شناسد. در این حالت، فهرست محصولات API را بر اساس این محدوده‌ها فیلتر می‌کنید. اگر محصولی دارای محدوده A یا X باشد، می‌توانید نقاط پایانی API را پیکربندی کنید که این محدوده‌ها را اعمال کنند. اگر محصولی محدوده A یا X نداشته باشد (مثلاً B، C و Z داشته باشد)، APIهایی که محدوده A یا X را اعمال می‌کنند نمی‌توانند با توکن فراخوانی شوند.

هنگامی که API را با توکن جدید فراخوانی می کنید:

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

رمز دسترسی توسط پروکسی API تأیید می شود. به عنوان مثال:

<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"
 }
 

موفقیت آمیز است زیرا خط مشی VerifyAccessToken به محدوده A یا X نیاز دارد، و نشانه دسترسی شامل محدوده A و X است. البته، اگر عنصر <Scope> روی "B" تنظیم شود، این فراخوانی ناموفق خواهد بود.

خلاصه

این مهم است که بدانیم Apigee Edge چگونه حوزه‌های OAuth 2.0 را مدیریت می‌کند. در اینجا نکات کلیدی مهم وجود دارد:

  • یک برنامه توسعه دهنده، اتحاد همه حوزه های تعریف شده برای همه محصولاتش را "تشخیص می دهد".
  • هنگامی که یک برنامه یک نشانه دسترسی درخواست می‌کند، این شانس را دارد که مشخص کند می‌خواهد چه محدوده‌هایی داشته باشد. این به Apigee Edge (سرور مجوز) بستگی دارد که بفهمد چه محدوده هایی را بر اساس (الف) محدوده (های) درخواست شده و (ب) آنهایی که توسط برنامه توسعه دهنده شناسایی می شوند، به توکن دسترسی اختصاص می دهد.
  • اگر Apigee Edge برای بررسی محدوده پیکربندی نشده باشد (عنصر <Scope> در خط مشی VerifyAccessToken وجود ندارد یا خالی است)، تا زمانی که محدوده تعبیه شده در نشانه دسترسی با یکی از حوزه های شناسایی شده مطابقت داشته باشد، فراخوانی API موفقیت آمیز خواهد بود. توسط برنامه توسعه‌دهنده ثبت‌شده (یکی از حوزه‌های موجود در فهرست دامنه‌های «مستر» برنامه).
  • اگر یک نشانه دسترسی دارای هیچ حوزه‌ای مرتبط با آن نباشد، تنها در مواردی موفق خواهد شد که Edge دامنه را در نظر نگیرد (عنصر <Scope> در خط‌مشی VerifyAccessToken وجود ندارد یا خالی است).