การทำงานกับขอบเขต OAuth2

คุณกำลังดูเอกสารประกอบของ Apigee Edge
ไปที่เอกสารประกอบของ Apigee X
ข้อมูล

หัวข้อนี้จะกล่าวถึงวิธีใช้ขอบเขต OAuth 2.0 ใน Apigee Edge

ขอบเขต OAuth2 คืออะไร

ขอบเขต OAuth 2.0 เป็นวิธีจำกัดจำนวนการเข้าถึงที่มอบให้กับโทเค็นเพื่อการเข้าถึง ตัวอย่างเช่น โทเค็นเพื่อการเข้าถึงที่ออกให้แอปไคลเอ็นต์อาจได้รับสิทธิ์ในการอ่านและเขียนทรัพยากรที่มีการป้องกัน หรือมีเพียงสิทธิ์การอ่านเท่านั้น คุณสามารถนำ API ไปใช้เพื่อบังคับใช้ขอบเขต หรือรวมขอบเขตใดก็ได้ตามต้องการ ดังนั้นหากไคลเอ็นต์ได้รับโทเค็นที่มีขอบเขต READ และพยายามเรียกใช้ปลายทาง API ที่ต้องใช้สิทธิ์ "การเขียน" การเรียกจะล้มเหลว

ในหัวข้อนี้ เราจะพูดถึงการกำหนดขอบเขตสำหรับโทเค็นเพื่อการเข้าถึงและวิธีที่ Apigee Edge บังคับใช้ขอบเขต OAuth 2.0 หลังจากอ่านหัวข้อนี้แล้ว คุณจะใช้ขอบเขตได้อย่างมั่นใจ

มีการกำหนดขอบเขตให้กับโทเค็นเพื่อการเข้าถึงอย่างไร

เมื่อ Edge สร้างโทเค็นเพื่อการเข้าถึงแล้ว 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"
}

ข้อมูลเมตาของโทเค็นประกอบด้วยสตริงโทเค็นเพื่อการเข้าถึงจริง ข้อมูลวันหมดอายุ การระบุแอปของนักพัฒนาซอฟต์แวร์ นักพัฒนาซอฟต์แวร์ และผลิตภัณฑ์ที่เชื่อมโยงกับโทเค็น นอกจากนี้ คุณจะเห็นว่าข้อมูลเมตามี "ขอบเขต" ด้วย

โทเค็นนี้มีขอบเขตอย่างไร

กุญแจสำคัญข้อแรกในการทำความเข้าใจขอบเขตคือ อย่าลืมว่าผลิตภัณฑ์แต่ละรายการในแอปนักพัฒนาซอฟต์แวร์สามารถมอบหมายขอบเขตได้เป็น 0 หรือมากกว่าก็ได้ คุณกำหนดขอบเขตเหล่านี้ได้เมื่อมีการสร้างผลิตภัณฑ์ หรือจะเพิ่มในภายหลังก็ได้ ข้อมูลเหล่านี้เป็นลิสต์รายการชื่อ และรวมอยู่ใน "ข้อมูลเมตา" ที่เชื่อมโยงกับผลิตภัณฑ์แต่ละรายการ

เมื่อคุณสร้างแอปนักพัฒนาแอปและเพิ่มผลิตภัณฑ์ลงในแอป 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 ได้รับคำขอนี้ จะรู้ว่าแอปใดที่ส่งคำขอและรู้ว่าไคลเอ็นต์ลงทะเบียนแอปใดไว้ (รหัสไคลเอ็นต์และคีย์รหัสลับไคลเอ็นต์มีการเข้ารหัสในส่วนหัวการตรวจสอบสิทธิ์พื้นฐาน) เนื่องจาก Edge ต้องตัดสินใจว่าผลิตภัณฑ์ API ที่เชื่อมโยงกับแอปของนักพัฒนาแอปมีขอบเขต "A" หรือไม่ เนื่องจากมีพารามิเตอร์การค้นหา scope รวมอยู่ด้วย หากอนุญาต ระบบจะสร้างโทเค็นเพื่อการเข้าถึงโดยมีขอบเขต "A" อีกวิธีหนึ่งในการดูกรณีนี้คือพารามิเตอร์การค้นหาขอบเขตเป็นตัวกรองประเภทหนึ่ง หากแอปนักพัฒนาแอปรู้จักขอบเขต "A, B, X" และพารามิเตอร์การค้นหาระบุ "scope=X Y Z" ระบบจะกำหนดขอบเขต "X" ให้กับโทเค็นเท่านั้น

จะเกิดอะไรขึ้นหากไคลเอ็นต์ไม่แนบพารามิเตอร์ขอบเขต ในกรณีนี้ Edge จะสร้างโทเค็นที่มีขอบเขตทั้งหมดที่แอปนักพัฒนาแอปรู้จัก คุณควรเข้าใจว่าลักษณะการทำงานเริ่มต้นคือการแสดงผลโทเค็นเพื่อการเข้าถึงที่มีการรวมขอบเขตทั้งหมดสำหรับผลิตภัณฑ์ทั้งหมดที่รวมอยู่ในแอปนักพัฒนาแอป

หากไม่มีผลิตภัณฑ์ที่เชื่อมโยงกับแอปนักพัฒนาแอประบุขอบเขต และโทเค็นมีขอบเขต การเรียกใช้ด้วยโทเค็นนั้นจะล้มเหลว

สมมติว่าแอปนักพัฒนาแอปรู้จักขอบเขตเหล่านี้: A B C D นี่คือรายการขอบเขตหลักของแอป อาจเป็นไปได้ว่าผลิตภัณฑ์รายการหนึ่งในแอปมีขอบเขต A และ B และผลิตภัณฑ์รายการที่ 2 มีขอบเขต C และ D หรือผสมแบบใดก็ได้ หากไคลเอ็นต์ไม่ได้ระบุพารามิเตอร์ scope (หรือหากระบุพารามิเตอร์ขอบเขตโดยไม่มีค่า) โทเค็นจะได้รับขอบเขตทั้ง 4 ขอบเขต ได้แก่ A, B, C และ D เช่นเดียวกัน โทเค็นจะได้รับชุดขอบเขตที่เป็นการรวมขอบเขตทั้งหมดที่แอปนักพัฒนาแอปรู้จัก

มีอีก 1 กรณีที่ลักษณะการทำงานเริ่มต้นคือการแสดงผลโทเค็นเพื่อการเข้าถึงที่มีขอบเขตที่รู้จักทั้งหมด ซึ่งก็คือเมื่อนโยบาย 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 (โดยปกติจะอยู่ที่จุดเริ่มต้นของโฟลว์พร็อกซี) นโยบายนี้ต้องระบุการดำเนินการ ConfirmAccessToken มาดูนโยบายนี้กัน

<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 เพื่อบังคับใช้ขอบเขตที่เฉพาะเจาะจงได้ด้วยความสามารถในการตรวจสอบโทเค็นเพื่อการเข้าถึงตามขอบเขต ซึ่งทำได้ด้วยการออกแบบขั้นตอนที่กำหนดเองโดยมีนโยบาย ConfirmAccessToken ที่คำนึงถึงขอบเขตแนบอยู่

สมมติว่า 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 ของตนเอง ซึ่งทำได้โดยการสร้างขั้นตอนที่กำหนดเองเพื่อจัดการขอบเขตเฉพาะ และแนบนโยบาย ConfirmAccessToken เพื่อบังคับใช้ขอบเขตเหล่านั้น

ตัวอย่างโค้ด

สุดท้ายนี้ มาดูตัวอย่างการเรียก 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" (ซึ่งก็คือ ConfirmAccessToken ต้องมีขอบเขต "A") นโยบาย ConfirmAccessToken มีดังนี้

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

วิธีการนี้ประสบความสำเร็จเนื่องจากนโยบาย ConfirmAccessToken ที่ทริกเกอร์เมื่อเรียกใช้ปลายทางจำเป็นต้องมีขอบเขต A และโทเค็นเพื่อการเข้าถึงได้รับขอบเขต A, B และ C ซึ่งเป็นลักษณะการทำงานเริ่มต้น

ตัวพิมพ์การกรอง

สมมติว่าคุณมีแอปสำหรับนักพัฒนาซอฟต์แวร์ซึ่งมีผลิตภัณฑ์ที่มีขอบเขต ก, ข, ค และ X คุณขอโทเค็นเพื่อการเข้าถึงและรวมพารามิเตอร์การค้นหา 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 เป็นขอบเขตที่ถูกต้อง โปรดทราบว่าแอปนักพัฒนาแอปรู้จักขอบเขต 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"
 }
 

ซึ่งทำได้สำเร็จเนื่องจากนโยบาย ConfirmAccessToken กําหนดขอบเขต A หรือ X และโทเค็นเพื่อการเข้าถึงมีขอบเขต A และ X แน่นอนว่า หากตั้งค่าองค์ประกอบ <Scope> เป็น "B" การเรียกนี้จะล้มเหลว

สรุป

คุณควรทำความเข้าใจวิธีที่ Apigee Edge จัดการขอบเขตของ OAuth 2.0 ประเด็นสำคัญมีดังนี้

  • แอปของนักพัฒนาซอฟต์แวร์ "รู้จัก" จุดรวมของขอบเขตทั้งหมดที่กำหนดไว้สำหรับผลิตภัณฑ์ทั้งหมด
  • เมื่อแอปขอโทเค็นเพื่อการเข้าถึง แอปจะมีโอกาสระบุขอบเขตที่ต้องการ ทั้งนี้ขึ้นอยู่กับ Apigee Edge (เซิร์ฟเวอร์การให้สิทธิ์) ที่จะพิจารณาว่าขอบเขตใดจะกำหนดให้กับโทเค็นเพื่อการเข้าถึงตาม (ก) ขอบเขตที่ขอ และ (ข) ขอบเขตที่แอปนักพัฒนาแอปรู้จัก
  • หากไม่ได้กําหนดค่า Apigee Edge ให้ตรวจสอบขอบเขต (องค์ประกอบ <Scope> ไม่มีอยู่ในนโยบาย ConfirmAccessToken หรือไม่มี) การเรียก API จะสําเร็จตราบใดที่ขอบเขตที่ฝังในโทเค็นเพื่อการเข้าถึงตรงกับขอบเขตที่แอปของนักพัฒนาซอฟต์แวร์ที่ลงทะเบียนรู้จัก (หนึ่งในขอบเขตในรายการขอบเขต "หลัก" ของแอป)
  • หากโทเค็นเพื่อการเข้าถึงไม่มีขอบเขตใดๆ เชื่อมโยงอยู่ โทเค็นจะประสบความสำเร็จในกรณีที่ Edge ไม่พิจารณาขอบเขตเท่านั้น (ไม่มีองค์ประกอบ <Scope> จากนโยบาย ConfirmAccessToken หรือองค์ประกอบว่างเปล่า)