使用第三方 OAuth 權杖

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

在本主題中,我們會討論如何將外部產生的存取權杖、更新權杖或驗證碼匯入 Edge 權杖存放區。如要設定 Apigee Edge 來驗證在 Apigee Edge 以外產生的權杖,可以使用這項技巧。

在一般情況下,Apigee Edge 會產生並儲存 OAuth 權杖,然後將權杖傳回呼叫應用程式。然後,呼叫應用程式會在要求服務時將權杖傳回 Apigee Edge,而 Apigee Edge 會透過具備「Operation」(作業 = VerifyAccessToken) 的 OAuthV2 政策,驗證權杖是否有效。本主題說明如何設定 Apigee Edge,以儲存在其他位置產生的 OAuth 權杖,同時保有權杖驗證的部分,做法和 Edge 產生權杖的方式一樣。

範例

如要查看說明本主題所述技術的工作範例,請參閱 Apigee 委派權杖管理範例

指南簡介

假設您目前已有授權系統,並想要使用該系統產生的權杖或程式碼值來取代 Edge 產生的 OAuth2 權杖或程式碼值。接著,您就可以使用替代的權杖或程式碼發出安全 API Proxy 要求,Edge 會驗證這些要求是否由 Edge 產生。

部分背景

在一般情況下,Apigee Edge 會隨機產生由字母和數字組成的隨機字串,藉此產生權杖。Apigee Edge 會與該權杖、其他資料 (例如權杖核發時間、到期時間、權杖的有效 API 產品清單,以及範圍) 建立關聯。上述所有資訊都能在 OAuthV2 政策 (作業 = GenerateAccessToken) 自動產生的回應中傳回。回應的形式如下所示:

{
  "issued_at": "1469735625687",
  "application_name": "06947a86-919e-4ca3-ac72-036723b18231",
  "scope": "urn://example.com/read",
  "status": "approved",
  "api_product_list": "[implicit-test]",
  "api_product_list_json": ["implicit-test"],
  "expires_in": "1799", //--in seconds
  "developer.email": "joe@weathersample.com",
  "token_type": "BearerToken",
  "client_id": "U9AC66e9YFyI1yqaXgUF8H6b9wUN1TLk",
  "access_token": "zBC90HhCGmGlaMBWeZAai2s3za5j",
  "organization_name": "wwitman",
  "refresh_token_expires_in": "0", //--in seconds
  "refresh_count": "0"
}

access_token 屬性的值實際上是回應資料的查詢鍵。應用程式可以向 Edge 代管的 API Proxy 提出要求,並使用不記名權杖 zBC90HhCGmGlaMBWeZAai2s3za5j 和 Edge (具有 Operation = VerifyAccessToken) 的 OAuthV2 政策,藉此查詢權杖、擷取所有資訊,並根據該項資訊判斷所需 API Proxy 的權杖是否有效。 這就是所謂的「權杖驗證」。上述所有資訊都包含權杖。access_token 值只是查詢該資訊的方式。

另一方面,按照以下所述步驟,您可以將 Edge 設定為儲存符記,使其 access_token 值由外部服務產生。所有其他中繼資料可能都相同。舉例來說,假設您在 Apigee Edge 外部的系統產生「TOKEN-< 16 隨機號碼」> 形式的權杖,在此情況下,Apigee Edge 儲存的完整權杖中繼資料可能是:

{
  "issued_at": "1469735625687",
  "application_name": "06947a86-919e-4ca3-ac72-036723b18231",
  "scope": "urn://example.com/read",
  "status": "approved",
  "api_product_list": "[implicit-test]",
  "api_product_list_json": ["implicit-test"],
  "expires_in": "1799", //--in seconds
  "developer.email": "joe@weathersample.com",
  "token_type": "BearerToken",
  "client_id": "U9AC66e9YFyI1yqaXgUF8H6b9wUN1TLk",
  "access_token": "TOKEN-1092837373654221",
  "organization_name": "wwitman",
  "refresh_token_expires_in": "0", //--in seconds
  "refresh_count": "0"
}

在這種情況下,應用程式可以透過 OAuthV2 政策,並搭配「Operation」(作業) =「VerifyAccessToken」,向 Edge 代管的 API Proxy 提出要求,取得不記名權杖 TOKEN-1092837373654221 和 Edge 以進行驗證。您也可以對授權碼和更新權杖套用類似的匯入模式。

讓我們來談談驗證用戶端憑證

產生權杖的先決條件之一,是驗證提出要求的用戶端。根據預設,Apigee Edge 中的 OAuthV2/GenerateAccessToken 政策會以隱含形式驗證用戶端憑證。通常在 OAuthV2 權杖的要求中,client_id 和 client_secret 會傳入「Authorization」標頭中,並透過「HTTP 基本授權」進行編碼 (以冒號串連,然後採用 Base64 編碼)。Apigee Edge 中的 OAuthV2/GenerateAccessToken 政策會解碼該標頭並查詢 client_id,並驗證傳入的 client_secret 適用於該 client_id。如果該憑證知道 Apigee Edge,也就是有 6 個儲存在 Apigee Edge 中的開發人員應用程式含有憑證,而該憑證本身含有指定的 client_id 和 client_secret,即可達到此效果。

如果 Apigee Edge 無法驗證用戶端憑證,您必須先設計 API Proxy,使其產生權杖,才能透過其他方式明確驗證用戶端。通常是透過 Service callout 政策連線至網路中的遠端端點。

無論以隱含或明確方式,您必須確保產生權杖的 API Proxy 會先驗證用戶端憑證。請注意,驗證用戶端與產生存取權杖無關。您可以將 Apigee Edge 設為執行這兩種作業,或是兩者皆執行,或兩者都不執行。

如要讓 Apigee Edge 中的 OAuthV2/GenerateAccessToken 政策針對 Edge 商店驗證用戶端憑證,請在政策設定中將 <ExternalAuthorization> 元素設為 false,或完全省略。如要使用外部授權服務明確驗證用戶端憑證,請將 <ExternalAuthorization> 設為 true

雖然 Apigee Edge 可能無法驗證用戶端憑證,但仍須讓 client_id 能夠由 Apigee Edge 識別及管理。Apigee Edge 中的每個 access_token 無論是由 Apigee Edge 產生,或由外部系統產生,隨後再匯入 Apigee Edge,都必須與用戶端應用程式建立關聯,以 client_id 表示。因此,即使 Apigee Edge 的 OAuthV2/GenerateAccessToken 政策不會驗證 client_id 和 client_secret 相符,這項政策仍會驗證 client_id 有效、存在,且不會撤銷。因此設定前置步驟時,您可能需要透過 Edge Management API 匯入 client_id。

Apigee 第三方 OAuth 的政策流程

如要在 Apigee Edge 中使用第三方 OAuth 系統提供的權杖,產生存取權杖的流程應採用下列任一模式。

用戶端憑證外部驗證

  1. ServiceCallout:驗證傳入的用戶端憑證和取得外部權杖。
  2. ExtractVariablesJavaScript 步驟,從回應中擷取外部產生的權杖。
  3. AssignMessage 來設定名為 oauth_external_authorization_status 的特殊變數。這個值必須為 true,表示用戶端憑證有效。
  4. <ExternalAuthorization> 元素設為 trueOAuthV2/GenerateAccessToken,以及至少一項 <ExternalAccessToken><ExternalRefreshToken><ExternalAuthorizationCode> 其中之一。

用戶端憑證的內部驗證

  • ServiceCallout 取得外部權杖。
  • ExtractVariablesJavaScript 步驟,從回應中擷取外部產生的權杖。
  • <ExternalAuthorization> 元素設為 falseOAuthV2/GenerateAccessToken,以及至少一項 <ExternalAccessToken><ExternalRefreshToken><ExternalAuthorizationCode> 其中之一。

流程與政策設定注意事項

  • 如果要使用外部系統來驗證用戶端憑證,您必須制定能執行必要作業的政策流程。一般而言,建議您使用 Service callout 政策,將外部辨識的憑證傳送至外部驗證服務。外部驗證服務通常會傳回回應,如果憑證有效,也會傳回存取權杖。

  • 服務呼叫之後,API Proxy 必須剖析回應來擷取有效狀態,以及外部產生的 access_token,並可能為 refresh_token。

  • 在 OAuthV2/GenerateAccessToken 政策中,將 <StoreToken> 元素設為 true,然後將 <ExternalAuthorization> 元素設為 truefalse

    執行 OAuthV2/GenerateAccessToken 政策時,系統會讀取變數 oauth_external_authorization_status。如果已設定變數且值為 true,則 Apigee Edge 不會嘗試驗證用戶端憑證。如果未設定變數或值不正確,Apigee Edge 會嘗試驗證用戶端憑證。

  • OAuthV2 政策有三個元素,可讓您指定要匯入的外部資料:<ExternalAccessToken><ExternalRefreshToken><ExternalAuthorizationCode>。每個元素都接受資料流變數。Edge 政策會讀取這個變數,以找出外部產生的存取權杖、更新權杖或授權碼。您可以自行實作政策和邏輯,將外部權杖或程式碼放到適當的變數中。

    例如,以下 OAuthV2 政策中的設定會指示 Edge 在名為 external_token 的內容變數中尋找權杖。

    <ExternalAccessToken>external_token</ExternalAccessToken>
    

    而且也需要透過前一個步驟設定該變數。

  • 設定 oauth_external_authorization_status 變數時,設定這個變數的常見技巧是搭配 AssignVariable 元素使用 AssignMessage 政策,如下所示:

    <AssignMessage name="AssignMessage-SetVariable">
        <DisplayName>Assign Message - Set Variable</DisplayName>
        <AssignVariable>
            <Name>oauth_external_authorization_status</Name>
            <Value>true</Value>
        </AssignVariable>
        <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
    </AssignMessage>
    

    請注意,這項政策必須位於 OAuthV2 政策前,「作業 = GenerateAccessToken」。

OAuthV2 政策範例

如果 Edge 在流程變數 external_access_token 中找到權杖值,下列 OAuthV2 政策會產生 Apigee Edge 存取權杖。

<OAuthV2 name="OAuth-v20-Store-External-Token">
    <ExternalAccessToken>external_access_token</ExternalAccessToken>
    <ExternalAuthorization>true</ExternalAuthorization>
    <Operation>GenerateAccessToken</Operation>
    <GenerateResponse enabled="true">
        <Format>FORM_PARAM</Format>
    </GenerateResponse>
    <ReuseRefreshToken>false</ReuseRefreshToken>
    <StoreToken>true</StoreToken>
    <SupportedGrantTypes>
        <GrantType>client_credentials</GrantType>
    </SupportedGrantTypes>
    <ExpiresIn ref='flow.variable'>2400000</ExpiresIn>
</OAuthV2>

理論上,您可以將這個模式與任何第三方 OAuth2 授權服務套用。