Skip to main content
Version: Next

OAuth2

用途說明#

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

欄位配置說明#

變數類型預設值說明必填
scopearray of string為存取特定範圍資料名稱的列表。如 mandatory_scope 設定為true,則變為必填欄位。V
mandatory_scopebooleanfalse可設定是否要存取特定範圍之資料。V
provision_keystringtrue一個獨特的金鑰,當此插件加在某服務上時會產生。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時,插件會把驗證內容自請求移除。
accept_http_if_already_terminatedbooleanfalse當有請求被代理伺服器或負載終止,但標頭中有帶入 x-forwarded-proto: https 時,後續往API Manager之請求不論使用HTTP或是HTTPs皆會接受。此項設定適合於當API Manager不開放公開存取並且只使用代理伺服器或負載做為進入點時使用。
anonymousstring可設定"anonymous"使用者在驗證失敗時會使用此身份驗證。如此欄位為空,則請求之標頭沒帶上Authorization時會收到authentication failure 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 三種。 strict 模式會強制對所有的客戶在驗證以及標記端加上PKCE標準。 lax 模式則是會對公開客戶加上PKCE標準,已認證之客戶不會。 而 none 模式則對所有客戶不會加上此標準。不過在任何情況下,如有客戶在驗證端要求使用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. 後端會處理前端送過來的資訊並將資訊傳送至API Manager做處理,最後回傳一個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 端點送至API Manager。如客戶端有加上標頭 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. API Manager會回傳一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"