本頁適用於 Apigee 和 Apigee Hybrid。
查看
Apigee Edge 說明文件。
本主題將說明如何使用 Apigee 使用及強制執行 OAuth 2.0 範圍。
什麼是 OAuth2 範圍?
OAuth 2.0 範圍可用於限制授予存取權杖的存取權量。舉例來說,您可以將存取權存取符記核發給用戶端應用程式,授予該應用程式對受保護資源的讀取和寫入權限,或只授予讀取權限。您可以實作 API,強制執行任何範圍或範圍組合。因此,如果用戶端收到具有「READ」範圍的權杖,但嘗試呼叫需要「WRITE」存取權的 API 端點,則呼叫會失敗。
在本主題中,我們將討論如何將範圍指派給存取權杖,以及 Apigee 如何強制執行 OAuth 2.0 範圍。閱讀完本主題後,您就能放心使用權限範圍。
如何將權限範圍指派給存取權杖?
Apigee 產生存取權杖時,可能會為該權杖指派範圍。如要瞭解發生這種情況的原因,您必須先熟悉以下 Apigee 實體:API 產品、開發人員和開發人員應用程式。如需相關簡介,請參閱「發布功能簡介」。建議您在繼續操作前,先查看這份說明資料 (如有需要)。
存取權杖是一串看似隨機的字元,可讓 Apigee 驗證傳入的 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" }
權杖的中繼資料包括實際的存取權杖字串、到期日資訊、與權杖相關聯的開發人員應用程式、開發人員和產品的識別資訊。您也會注意到,中繼資料也包含「範圍」。
權杖如何取得範圍?
如要瞭解範圍,首先請記住,開發人員應用程式中的每項產品都可以指派零個或多個範圍。您可以在建立產品時指派這些範圍,也可以稍後再新增。這些名稱會以清單形式存在,並納入與每個產品相關的「中繼資料」中。
當您建立開發人員應用程式並新增產品時,Apigee 會查看開發人員應用程式中的所有產品,並建立這些產品的所有範圍清單 (應用程式的主或全域範圍清單,也就是所有已知範圍的聯集)。
當用戶端應用程式向 Apigee 要求存取權權杖時,可以選擇指定要與該權杖相關聯的範圍。舉例來說,下列要求會要求範圍「A」。也就是說,用戶端要求授權伺服器 (Apigee) 產生範圍為「A」的存取權杖 (授予應用程式呼叫範圍為「A」的 API 的授權)。應用程式會傳送類似以下的 POST 要求:
curl -i -X POST -H Authorization: Basic Mg12YTk2UkEIyIBCrtro1QpIG \ -H content-type:application/x-www-form-urlencoded \ https://apitest.acme.com/oauth/token?grant_type=client_credentials&scope=A
會發生什麼情況?
Apigee 收到這項要求時,會知道哪個應用程式提出要求,以及用戶端註冊的開發人員應用程式 (用戶端 ID 和用戶端密碼金鑰會在基本驗證標頭中編碼)。由於已納入 scope
查詢參數,Apigee 需要判斷與開發人員應用程式相關聯的任何 API 產品是否具有「A」範圍。如果是的話,系統就會產生範圍為「A」的存取權杖。換個角度來看,範圍查詢參數是一種篩選器。如果開發人員應用程式可辨識「A、B、X」範圍,且查詢參數指定「scope=X Y Z」,則只有「X」範圍會指派給權杖。
如果用戶端未附加範圍參數,該怎麼辦?在這種情況下,Apigee 會產生權杖,其中包含開發人員應用程式所辨識的所有權限。請務必瞭解,預設行為是傳回權杖,其中包含開發人員應用程式所包含的所有產品的所有權限的聯集。
如果與開發人員應用程式相關聯的產品都未指定範圍,而權杖確實有範圍,則使用該權杖所做的呼叫會失敗。
假設開發人員應用程式可辨識以下範圍:A、B、C、D。這是應用程式的範圍主清單。應用程式中的第一個產品可能有範圍 A 和 B,第二個產品則有範圍 C 和 D,或任何組合。如果用戶端未指定 scope
參數 (或指定範圍參數但沒有值),則權杖會授予所有四個範圍:A、B、C 和 D。同樣地,符記會接收一組權限範圍,也就是開發人員應用程式所辨識的所有權限範圍的聯集。
還有一種情況是,預設行為會傳回包含所有已知範圍的存取權權杖,也就是當 GenerateAccessToken 政策 (產生存取權權杖的 Apigee 政策)「未」指定 <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 中,存取權存取金鑰會透過 OAuthV2 政策進行驗證 (通常會放在 Proxy 流程的開頭)。政策必須指定 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 \ https://apitest.acme.com/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 \ https://apitest.acme.com/scopecheck1/resourceA
這項 GET 呼叫成功:
{ "hello" : "Tue, 25 Nov 2014 01:35:53 UTC" }
這是因為在呼叫端點時觸發的 VerifyAccessToken 政策需要範圍 A,而存取權杖已授予範圍 A、B 和 C,這是預設行為。
篩選案件
假設您的開發人員應用程式含有範圍為 A、B、C 和 X 的產品。您可以要求存取權杖,並納入 scope
查詢參數,如下所示:
curl -i -X POST -H content-type:application/x-www-form-urlencoded \ 'https://apitest.acme.com/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),則無法使用憑證呼叫會強制執行 A 或 X 範圍的 API。
使用新權杖呼叫 API 時:
curl -X GET -H Authorization: Bearer Rkmqo2UkEIyIBCrtro1QpIG \ https://apitest.acme.com/scopecheck1/resourceX
API Proxy 會驗證存取權杖。例如:
<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 如何處理 OAuth 2.0 範圍。以下是主要重點:
- 開發人員應用程式會「辨識」為所有產品定義的所有範圍的聯集。
- 應用程式要求存取權杖時,可以指定要取得哪些範圍。Apigee (授權伺服器) 會根據 (a) 要求的範圍和 (b) 開發人員應用程式所辨識的範圍,判斷實際要將哪些範圍指派給存取權權杖。
- 如果未設定 Apigee 檢查範圍 (VerifyAccessToken 政策缺少
<Scope>
元素或為空白),只要存取權權杖中嵌入的範圍與註冊開發人員應用程式所辨識的範圍相符 (應用程式「主」範圍清單中的其中一個範圍),API 呼叫就會成功。 - 如果存取權杖沒有任何相關聯的範圍,則只有在 Apigee 不考量範圍 (VerifyAccessToken 政策缺少
<Scope>
元素或為空白) 的情況下,存取權杖才會成功。