使用 OAuth2 範圍

您正在查看 Apigee Edge 說明文件。
查看 Apigee X 說明文件
資訊

本主題將說明如何在 Apigee Edge 中使用 OAuth 2.0 範圍。

OAuth2 範圍是什麼?

OAuth 2.0 範圍可讓您限制授予存取權杖的存取權數量。舉例來說,核發給用戶端應用程式的存取權杖可能會取得受保護的資源的 READ 和 WRITE 權限,或是單純取得 READ 存取權。您可以實作 API,強制執行所需的任何範圍或組合。因此,如果用戶端收到具有 READ 範圍的憑證,並嘗試呼叫需要 WRITE 存取權的 API 端點,呼叫就會失敗。

在本主題中,我們會討論為存取權杖指派範圍的方式,以及 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"
}

權杖的中繼資料包含實際存取權杖字串、到期時間資訊、開發人員應用程式識別資訊、開發人員,以及與權杖相關聯的產品。您也會發現中繼資料內包含「範圍」。

權杖如何取得範圍?

瞭解範圍的第一個重要關鍵,是請記住,開發人員應用程式中的每項產品都能為零或多個產品指派範圍。您可以在建立產品時指派這些範圍,也可以之後再新增。這些屬性是以名稱清單的形式呈現,包含在與各項產品相關聯的「中繼資料」中。

在您建立開發人員應用程式並將產品新增至其中時,Edge 會查看開發人員應用程式中的所有產品,並建立這些產品的所有範圍清單 (應用程式的主要範圍或全域範圍清單,也就是所有辨識範圍的聯集)。

當用戶端應用程式向 Apigee Edge 要求存取權杖時,可以選擇指定要與該權杖建立關聯的範圍。例如,下列要求要求範圍「A」範圍。也就是說,用戶端要求授權伺服器 (Edge) 產生範圍為「A」的存取權杖 (授予應用程式授權以呼叫範圍為「A」的 API)。應用程式會傳送 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 收到這項要求後,就會知道發出要求的是哪個應用程式,而且會知道用戶端註冊的是哪個開發人員應用程式 (用戶端 ID 和用戶端密鑰編碼在基本驗證標頭中)。由於包含 scope 查詢參數,因此 Edge 必須判斷是否有任何與開發人員應用程式相關聯的 API 產品擁有「A」範圍。否則系統會產生範圍為「A」的存取權杖。另一個做法是範圍查詢參數是篩選器的類型。如果開發人員應用程式辨識出範圍「A、B、X」範圍,且查詢參數指定了「scope=X Y Z」,則系統只會將範圍「X」指派給該權杖。

如果用戶端沒有附加範圍參數,該怎麼辦?在這種情況下,Edge 會產生權杖,其中包含開發人員應用程式辨識的所有範圍。請務必瞭解,預設行為是傳回存取權杖,其中包含開發人員應用程式中所有產品的所有範圍聯集。

如果與開發人員應用程式相關聯的產品均未指定範圍,且權杖具有範圍,使用該權杖的呼叫就會失敗。

假設某個開發人員應用程式識別了以下範圍:B C D。這是應用程式的主要範圍清單。這可能是因為應用程式中的某項產品具有範圍 A 和 B 的範圍,而第二個產品具有範圍 C 和 D 的範圍,或者任何組合。如果用戶端未指定 scope 參數 (或指定沒有值的範圍參數),符記就會授予所有四個範圍:A、B、C 和 D。再次提醒,憑證會接收一組範圍,構成開發人員應用程式識別的所有範圍聯集。

另有一種預設行為是傳回具備所有已辨識範圍的存取權杖,也就是 GenerateAccessToken 政策 (產生存取權杖的 Apigee Edge 政策) 並未指定 <Scope> 元素。例如,以下是指定 <Scope> 的 GenerateAccessToken 政策。如果缺少該 <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 政策進行驗證 (通常位於 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 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"
}

現在,假設您有一個範圍為「A」的 API 端點 (也就是說,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"
 }

之所以會成功,是因為呼叫端點時需要範圍 A 範圍時觸發的 VerifyAccessToken 政策,並將存取權杖授予 A、B 和 C 範圍,也就是預設行為。

篩選大小寫

假設您有一個開發人員應用程式,其中的產品具有 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),就無法使用權杖呼叫強制執行範圍 A 或 X 的 API。

使用新權杖呼叫 API 時:

curl -X GET -H Authorization: Bearer Rkmqo2UkEIyIBCrtro1QpIG http://wwitman-test.apigee.net/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 Edge 如何處理 OAuth 2.0 範圍。以下提供要點:

  • 開發人員應用程式會「辨識」為所有產品定義的所有範圍聯集。
  • 當應用程式要求存取權杖時,可以指定要擁有的範圍。Apigee Edge (授權伺服器) 可以根據 (a) 要求的範圍,以及 (b) 開發人員應用程式已辨識的範圍,找出實際指派給存取權杖的範圍。
  • 如果 Apigee Edge 未設定檢查範圍 (VerifyAccessToken 政策缺少 <Scope> 元素或該元素為空白),則只要嵌入存取權杖的範圍與註冊開發人員應用程式辨識的其中一個範圍 (應用程式「主要」範圍清單中的其中一個範圍) 相符,API 呼叫就會成功。
  • 如果存取權杖沒有任何相關聯的範圍,則只有在 Edge 未考量範圍 (亦即 VerifyAccessToken 政策缺少 <Scope> 元素或該元素為空的) 時,權杖才會成功。