Skip to main content
Version: 2.8.1

OAuth2

用途說明#

可新增 OAuth 2.0 驗證。依據不同適用情境,有 Authorization Code GrantClient CredentialsImplicit GrantResource Owner Password Credentials Grant 以上不同授權流程模式。

欄位配置說明#

變數類型預設值說明必填
scopesarray of string為存取特定範圍資料名稱的列表。如 mandatory_scope 設定為 true,則變為必填欄位。
mandatory_scopebooleanfalse可設定是否要存取特定範圍之資料。V
provision_keystring一個獨特的金鑰,當此插件加在某服務上時會產生。V
token_expirationnumber7200可自由設定一個 token 存活時間,當 token 存活超過此設定時間則會更新。當設定為 0 時則等於關閉此功能。V
enable_authorization_codebooleanfalse開啟 three-legged Authorization Code 流程 (RFC 6742 Section 4.1)V
enable_client_credentialsbooleanfalse開啟 Client Credentials Grant 流程 (RFC 6742 Section 4.4)V
enable_implicit_grantbooleanfalse開啟允許提供 token 作為驗證結果的 Implicit Grant 流程 (RFC 6742 Section 4.2)V
enable_password_grantbooleanfalse開啟 Resource Owner Password Credentials Grant 流程 (RFC 6742 Section 4.3)V
auth_header_namestringauthorization設定攜帶 access token 的標頭名。預設為 authorization
hide_credentialsbooleanfalse此欄位決定將請求往後送至服務時是否帶上原本的驗證標頭內容。
設定為 true 時,插件會把驗證內容自請求移除。
V
accept_http_if_already_terminatedbooleanfalse當有請求被代理伺服器或負載終止,但標頭中有帶入 x-forwarded-proto: https 時,後續往 GOC API Gateway 之請求不論使用HTTP或是HTTPs皆會接受。此項設定適合於當 GOC API Gateway 不開放公開存取並且只使用代理伺服器或負載做為進入點時使用。V
anonymousstring可設定 anonymous 使用者在驗證失敗時會使用此身份當作匿名用戶。
若此欄位為空,則當執行請求的身份認證時失敗時,會收到身份驗證失敗 4xx 的回應。
*要注意的是,此欄位需填入的是 consumer 本身之 id,而不是 custom_id 。
global_credentialsbooleanfasle開啟此項設定將允許其它也開啟此項設定之服務都能使用由插件產生同樣的憑證。V
refresh_token_ttlnumber1209600Token/Refresh token 的使用期限,可用來產生新的 access token。
預設時間為兩週,如設定為 0,則為無限期。
V
reuse_refresh_tokenbooleanfalse當 refresh token 更新 access token 後還能重複使用。V
pkcestringlax決定使用 PKCE 的方式。
此欄位接受輸入的值為以下其一: nonelax 以及 strict
none 模式則對所有客戶不會加上此標準。不過在任何情況下,如有客戶在驗證端要求使用PKCE,則在標記端也會被強制加上此標準。
lax 模式則是會對公開客戶加上PKCE標準,已認證之客戶不會。
strict 模式會強制對所有的客戶在驗證以及標記端加上PKCE標準。

用法示例#

在全局啟用插件#

  1. 從網站左邊 Menu 中 外掛插件 頁面中,點選右上角的 新增外掛插件

全局啟用畫面

  1. 點選後,選擇 認證 頁籤,並啟用 OAuth2,填寫內容參考欄位配置說明,設定成功後,任何請求(不分服務、路由、用戶)皆需經過認證才能通過。

在服務端上啟用插件#

  1. 從網站左邊 Menu 中 服務 > 服務列表 頁面中,選擇要啟用此插件的服務,假設為 google,點選對應的編輯按鈕:

服務啟用畫面1

  1. 在編輯畫面中,點選上方的 外掛插件 頁籤,再點選頁籤內容上方的 新增外掛插件 按鈕:

服務啟用畫面2

點選後,選擇 認證 頁籤,並啟用 OAuth2,填寫內容參考欄位配置說明,設定成功後,僅有此服務(範例為google)請求需經過認證才能通過。

在路由端上啟用插件#

可以由兩種方式來選擇路由,並啟用插件:

方式一:路由列表#

  1. 從網站左邊 Menu 中 服務 > 路由列表 頁面中,選擇要啟用此插件的路由,假設為 google,點選對應的編輯按鈕:

路由啟用畫面1

方式二:服務 > 服務列表 > 路由列表#

  1. 從網站左邊 Menu 中 服務 > 服務列表 頁面中,選擇要啟用此插件的路由 所屬之服務(假設為 google),點選對應的編輯按鈕。

在編輯畫面中,點選上方的 路由 頁籤,選擇要啟用此插件的路由(假設為 google),點選對應的編輯按鈕:

路由啟用畫面2


  1. 承第1步,點擊上述兩種方式之一的編輯按鈕後,在編輯畫面中,點選上方的 外掛插件 頁籤,再點選頁籤內容上方的 新增外掛插件 按鈕:

路由啟用畫面3

點選新增外掛插件 按鈕後,選擇 認證 頁籤,並啟用 OAuth2,填寫內容參考欄位配置說明,設定成功後,僅有此路由(範例為google)請求需經過認證才能通過。

建立使用者及憑證#

  1. 從網站左邊 Menu 中 訂閱用戶 > 用戶列表 頁面中選擇右上方 新增 按鈕,新增用戶。

  2. 選擇剛建立的使用者,進入編輯頁面,選擇上方 憑證 頁籤,然後選擇左邊 OAuth2 頁籤,再選擇列表左上方的 新增 按鈕。

oauth2

  1. 填入代表此憑證的名稱以及 重新導向URIs,客戶ID 及 客戶密鑰 可自行輸入或是留空自動生成。在此於名稱填入 Hello World 及 重新導向URIs 填入 https://google.com 做為範例。下圖為自動生成 客戶ID 及 客戶密鑰 之結果。

oauth2-2

oauth2-3

端點#

當客戶端藉由 proxy port 關注其底下之服務,OAuth 2.0 會監聽以下端點。

端點描述
/oauth2/authorize在使用 Authorization Code 流程時,此端點會提供認證碼;或是在 Implicit Grant 流程時提供存取權杖。僅支援 POST 方法。
/oauth2/token此端點提供存取權杖,對於 Client Credentials 及 Resource Owner Password Credentials Grant 流程也是唯一可使用之端點。僅支援 POST 方法。

客戶端必需使用這些端點做驗證並取得存取權杖。要注意的是這些端點必須要結合對的 URI 路徑以及標頭才能正確的使用。

流程與驗證#

Client Credentials#

Client Credentials 流程可以直接使用,不需要再另外建立一個驗證的頁面。客戶端需要使用 /oauth2/token 端點來取得存取權杖。

Authorization Code#

Authorization 流程需先準備驗證的網頁頁面,驗證網頁由以下兩個部分組成:

  1. 前端網頁可允許使用者驗證客戶端應用來存取遠端資料。
  2. 後端會處理前端送過來的資訊並將資訊傳送至 GOC API Gateway 做處理,最後回傳一個 URL。

可以參考範例來瞭解此流程詳細內容。

驗證#

經過認證頁面後,後端會使用以下指令來取得 redirect_uri

$ curl -X POST https://your.service.com/oauth2/authorize \
--header "Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW" \
--data "client_id=XXX" \
--data "response_type=XXX" \
--data "scope=XXX" \
--data "provision_key=XXX" \
--data "authenticated_userid=XXX"
  • provision_key 是在服務開啟此 plugin 時會得到的一把鑰匙。
  • authenticated_userid 是取得權限登入驗證頁面的使用者 ID。

送出以上指令後會取得 JSON 回應:

{
"redirect_uri": "http://some/url"
}

回應會帶著狀態碼 200 OK 或是 400 Bad Request 來表示成功或失敗。

取得的 uri 中會帶有 code 的 query string,利用此 query string,可以取得存取權杖。使用以下指令取得存取權杖:

$ curl -X POST \
--url "https://your.service.com/oauth2/token" \
--header "Host: your host" \
--data "grant_type=authorization_code" \
--data "client_id=XXX" \
--data "client_secret=XXX" \
--data "redirect_uri=http://some/url" \
--data "code=XXX" \
--insecure

送出以上指令後會取得 JSON 回應:

{
"refresh_token": "N8YXZFNtx0onuuR7v465nVmnFN7vBKWk",
"token_type": "bearer",
"access_token": "njVmea9rlSbSUtZ2wDlHf62R7QKDgDhG",
"expires_in": 7200
}

現在可以使用此 access_token 來通過驗證:

curl -X GET \
--url "http://your.service.com" \
--header "Host: your host" \
--header "Authorization: bearer njVmea9rlSbSUtZ2wDlHf62R7QKDgDhG"

Resource Owner Password Credentials#

Resource Owner Password Credentials 流程不需要前端認證頁面,但還是需要後端做處理。

  1. 客戶端應用需傳送請求,並攜帶 OAuth2 參數,包括 username 以及 password

  2. 後端接收到此請求後會驗證此 username 以及 password 正確後,會加上 provision_keyauthenticated_userid 以及 grant_type 等參數使用 /oauth2/token 端點送至 GOC API Gateway。如客戶端有加上標頭 Authorization 則也必須在請求加上此標頭。以下為範例:

$ curl https://your.service.com/oauth2/token \
--header "Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW" \
--data "client_id=XXX" \
--data "client_secret=XXX" \
--data "grant_type=password" \
--data "scope=XXX" \
--data "provision_key=XXX" \
--data "authenticated_userid=XXX" \
--data "username=XXX" \
--data "password=XXX"
  • provision_key 是在服務開啟此 plugin 時會得到的一把鑰匙。
  • authenticated_userid 是取得權限登入驗證頁面的使用者 ID。
  1. GOC API Gateway 會回傳一 JSON 回應。

  2. 回應必須送回原本送出請求之客戶端。如成功則回應中會包含存取權杖,否則將包含錯誤訊息。

Refresh Token#

當存取權杖到期,必須藉由更新權杖生成新的存取權杖:

curl -X POST https://your.service.com/oauth2/token \
--data "grant_type=refresh_token" \
--data "client_id=XXX" \
--data "client_secret=XXX" \
--data "refresh_token=XXX"