使用外部授權 API
API 網關支持外部授權功能。通過該功能,用戶可以在網關將請求轉發給 real-server 之前,插入一個自定義的遠程接口。網關會先將請求轉發給這個自定義接口,該接口繼而選擇是否允許這個請求正常轉發到 real-server。
如下圖所示,步驟 2 即為調用自定義的遠程接口。
本文將引導您使用外部授權 API。完整的操作步驟如下:
編寫外部授權 API:在本地開發定義一個外部授權接口服務。
創建外部授權 API:在 API 網關控制臺,配置對應的外部授權 API。
綁定 API:將創建好的外部授權 API 綁定一個 API,使其生效。
編寫外部授權 API
您需要在本地開發一個外部授權接口。當 API 需要驗證授權關系時,會調用該外部授權接口進行授權校驗。外部授權接口不限制協議類型,但會限制請求體和響應體。請求和響應均為 JSON 字符串,格式如下:
請求體
{ "context" : { "key": "value" } }
字段說明:Request 中只有一個 context 字段,格式為 kv。這些參數來自于 client 的 request,需要在 API 網關控制臺平臺進行配置。
響應體
{ "success" : true/false, "principal" : { "key" : "value" }, "failResponseHeader" : { "key" : "value" }, "failResponseBody": jsonarray/jsonobject "failResponseStatus": ${httpcode} }
字段說明:
success
:是否允許該請求轉發到 real-server。principal
:如果允許轉發到 real-server,可以將一些信息傳遞給 real-server,kv 格式。如果 real-server 是 HTTP 接口,則 principal 會放到 header 中。
如果 real-server 是 SOFARPC 接口,則 principal 會放到 baggage 中。
failResponseHeader
:如果不允許轉發到 real-server,可以設置響應頭返回給 client。failResponseBody
:如果不允許轉發到 real-server,可以設置響應 body 給 client。failResponseStatus
:如果不允許轉發到 real-server,可以設置響應 HTTP 狀態碼。
對應外部授權 API 的定義標準如下:
AuthRequest
public class AuthRequest { private Map<String,String> context; }
AuthResponse
public class AuthResponse { private boolean success; private Map<String,String> principal; private Map<String, String> failResponseHeader; private Object failResponseBody; private int failResponseStatus; }
接口示例
@PostMapping("/testAuth") public AuthResponse testAuth(@RequestBody AuthRequest authRequest) { String sid = authRequest.getContext().get("sid"); AuthResponse response = new AuthResponse(); if (sid != null) { Map<String, String> principal = new HashMap<>(); principal.put("uid", sid + "_uid"); response.setSuccess(true); response.setPrincipal(principal); } else { response.setSuccess(false); Map<String, String> failResponseHeader = new HashMap<>(); String queryKey = request.getContext().get("queryKey"); if (queryKey.equalsIgnoreCase("q")) { failResponseHeader.put("header-to-client", "query"); } else { failResponseHeader.put("header-to-client", "no-query"); } response.setFailResponseHeader(failResponseHeader); Map<String, String> failResponseBody = new HashMap<>(); String bodyKey = request.getContext().get("bodyKey"); if (bodyKey.equalsIgnoreCase("b")) { failResponseBody.put("body-to-client", "b"); } else { failResponseBody.put("body-to-client", "no-b"); } response.setFailResponseBody(JSON.toJSONBytes(failResponseBody)); response.setFailResponseStatus(401); } return response; }
創建外部授權 API
本地編寫完外部授權接口后,您需要前往 API 網關的控制臺上配置一個對應的外部授權 API。操作步驟如下:
進入 API 網關控制臺頁面,在左側導航欄中選擇 API 發布 > 外部授權 API。
在外部授權 API 列表頁,點擊列表右上方的 創建外部授權 API。
在新打開的頁面中,選擇或輸入外部授權 API 相關信息:
外部授權 API 名稱:必填,用于識別該 API,支持英文字母、中文、數字、下劃線(_)、連接符(-),32 個字符以內,以中文或字母開頭。
后端服務類型:目前僅支持 系統集群,即表示網關接收到前端請求后轉發到真實業務系統的集群。
協議類型:目前支持 HTTP 和 SOFARPC 協議。
HTTP 協議:
請求路徑:必填,API 請求所指向的資源 URL。以斜杠(/)開頭,支持字母、數字、下劃線(_)、連接符(-),200 字符以內。格式示例:
/home/{id}
。方法:外部授權 API 必須使用 POST 方法,即將數據發送到服務器進行處理。
SOFARPC 協議:
接口名稱:必填,支持英文字母、數字、英文句號(.) 、冒號(:) 、@,以小寫字母作為開頭,格式示例:
com.alipay.testapp.xxxx.ConfigFacade:1.0@DEFAULT
。服務標識:選填,支持指定服務的 uniqueId。
方法名:支持英文字母和數字,以小寫字母作為開頭,格式示例:
getUserID
。
超時時間:必填,API 請求超時時間,單位為毫秒(ms)。
緩存開關:即選擇授權結果是否開啟緩存。
開啟緩存后,如果 auth-server 返回 success,該結果會被緩存,緩存有效期內不會再次請求 auth-server。
緩存時間不能超過 1 小時,不能低于 5s。
路由策略:必選,表示當網關接收到請求后使用的路由策略。詳見 創建路由規則。
系統集群:必選,選擇提供該認證服務的后端集群。
外部 API 參數:即
request.context
中的參數,可以從請求的 Header、Body、Cookie 和 Query 中提取。如上圖配置所示,網關在調用 auth-server 時,會進行如下參數提取:
從 Header 中取出 headerKey 的 value。
從 Query 中取出 queryKey 的 value。
從 Body 中取出 bodyKey 的 value。如 Body 為
{"bodyKey":"abc", "other": "xx"}
,則會取出abc
這個 value。使用上述所有的 kv 構造一個 context,然后調用 auth-server,最終的請求如下:{ "context" : { "bodyKey" : "abc", "queryKey" : "q", "headerKey": "h" } }
確認 API 配置無誤后,單擊 創建 即可。
綁定 API
外部授權 API 配置完成后,即可前往綁定 API 生效。操作步驟如下:
在 API 發布 > 外部授權 API 頁面,單擊剛剛創建的外部授權 API 名稱,進入其詳情頁。
在 外部授權 API 詳情 > 綁定的 API 標簽頁下,單擊 綁定 API。
在彈出的窗口中,選擇需要綁定的 API 后,單擊 確定 即可。
后續如需解綁,直接在 外部授權 API 詳情 > 綁定的 API 中,選擇需要解綁的 API,單擊其右側的 解除綁定 按鈕,然后確定即可。
一個業務 API 只能綁定一個外部授權 API。
外部授權 API 只能綁定相同前端協議的業務 API。