云原生網關支持自定義鑒權服務,方便在網關入口處完成鑒權,避免每個后端服務都接入鑒權服務。本文介紹如何為云原生網關配置自建認證鑒權。
背景信息
服務端通常根據客戶端請求攜帶的憑證信息(即Token)來保護對外暴露的API接口的通信安全。Token形式沒有嚴格規定,一般根據實際業務場景決定。
如果Token采用的是JSON WEB Token (JWT),那么在任何時間、任何地點都可以利用公鑰來對Token的簽名進行驗簽,無需訪問一個中心化的鑒權服務。
如果Token的形式是業務方自定義的格式,則服務端收到請求后,必須額外訪問中心化的鑒權服務來完成鑒權操作,以此保護API接口的通信安全。云原生網關支持自定義鑒權。
下面以一個示例來說明云原生網關接入自建的鑒權服務后的請求處理流程。
客戶端向網關發起認證請求,例如登錄操作。
網關將認證請求直接轉發給認證服務。
認證服務讀取請求中的驗證信息(例如用戶名、密碼)進行驗證,驗證通過后返回憑證信息(Token)給網關,由網關響應給客戶端。
客戶端向網關發起業務請求,例如下單操作/order,請求中攜帶上一步中身份認證成功后頒發的Token。
網關通過截取原始業務請求的Path(包含Query Parameters)、HTTP方法(GET、POST等)和Token來形成一個新的請求報文,向接入的自建鑒權服務發起鑒權請求。您需要在網關控制臺配置Token所在的HTTP Header,另外您可以根據需要開啟允許攜帶原始請求的Body。
假設自建鑒權服務的鑒權API是/validateToken,那么鑒權請求的真實Path是鑒權API加上原始業務請求的Path后的結果,即/validateToken/order。
鑒權服務收到鑒權請求后,既可以根據Token完成校驗Token合法性的操作,又可以根據原始業務請求的Path完成鑒權操作。
如果您鑒權服務的鑒權響應可以修改HTTP狀態碼,那么您可以利用HTTP狀態碼來反映鑒權結果。
鑒權服務返回HTTP狀態碼為200,表明Token合法且Token有權限訪問該后端資源。網關繼續將原始業務請求轉發給受保護的后端服務,收到業務響應后再次轉發給客戶端,完成下單操作。
鑒權服務返回HTTP狀態碼為401或者403,表明Token不合法或Token無權限訪問該后端資源。網關直接返回鑒權服務的響應給客戶端,此次下單操作失敗。
如果您的鑒權服務受業務本身限制要求鑒權響應的HTTP狀態碼統一為200,那么您可以利用內置的HTTP頭部
x-mse-external-authz-check-result
。鑒權服務的響應頭部
x-mse-external-authz-check-result
的結果為true
,表明Token合法或Token有權限訪問該后端資源。網關繼續將原始業務請求轉發給受保護的后端服務,收到業務響應后再次轉發給客戶端,完成下單操作。鑒權服務的響應頭部
x-mse-external-authz-check-result
的結果為false
,表明Token不合法或Token無權限訪問該后端資源。網關直接返回鑒權服務的響應給客戶端,此次下單操作失敗。
創建自建認證鑒權
登錄MSE網關管理控制臺。
在左側導航欄,選擇云原生網關 > 網關列表,并在頂部菜單欄選擇地域。
在網關列表頁面,單擊目標網關名稱。
在左側導航欄,選擇安全管理 > 全局認證鑒權。
在全局認證鑒權頁面,單擊創建鑒權,然后在創建鑒權面板,配置網關鑒權相關參數,最后單擊確定。
配置項
說明
鑒權名稱
自定義云原生網關鑒權的名稱。
鑒權類型
選擇自建的鑒權服務。
鑒權服務
選擇鑒權的后端服務,可以在服務管理中添加。相關內容,請參見添加服務。
說明僅支持選擇HTTP協議的服務,不支持Dubbo等其他協議的服務。
如果具有多個端口的K8s Service,則默認取第一個端口。如果您希望使用其他端口,需要在容器服務中創建一個額外的K8s Service且只使用目標端口。
鑒權API
設置鑒權服務提供的鑒權API的Path,API的Path需是前綴匹配。
例如,您的鑒權服務基于SpringMVC構建,對外開放的鑒權API為/check,那么處理/check/**的請求設置如下:
@RequestMapping("/check/**") public ResponseEntity<RestResult<String>> check(){}
Token位置
設置Token在請求報文中的Header位置,常見的有Authorization和Cookie。您可以選擇下拉選擇或手動輸入的方式設置Token位置。
鑒權請求中允許攜帶的頭部
如果需要額外攜帶客戶端請求中的頭部,那么需要在字段中按需配置頭部。
說明Host、Method、Path和Content-Length頭部會被默認添加,您無需手動添加。
鑒權響應中允許保留的頭部
如果需要將鑒權響應中的頭部添加到客戶端請求中,那么需要在字段中按需配置頭部。
說明如果客戶端請求中已經有該頭部,那么其值將會被覆蓋。
鑒權請求中允許攜帶Body
勾選鑒權請求中允許攜帶Body后,鑒權請求會包含原始請求的Body。
其中,Body最大字節數表示允許鑒權請求攜帶Body的最大字節數。單位:字節。
超時時間
設置等待鑒權服務返回結果的最大等待時間。單位:秒,默認超時時間為10秒。
模式
支持寬松模式和嚴格模式,建議您使用寬松模式。
寬松模式:當鑒權服務不可用時(鑒權服務建立連接失敗或者返回5xx請求),網關接受客戶端請求。
嚴格模式:當鑒權服務不可用時(鑒權服務建立連接失敗或者返回5xx請求),網關拒絕客戶端請求。
簡單條件授權
在授權右側單擊簡單條件。簡單條件授權模式支持白名單模式和黑名單模式。
白名單模式:白名單中的Hosts和Paths無需校驗即可訪問,其余Hosts和Paths都需要校驗。
黑名單模式:黑名單中的Hosts和Paths需要校驗,其余Hosts和Paths可直接訪問。
單擊+ 規則條件,設置請求域名、路徑和請求頭。
域名:請求訪問的域名,即Hosts。
路徑(Path):請求訪問的接口Path,即Paths。
路徑匹配條件:Path支持精確匹配、前綴匹配和正則匹配。
精確匹配:輸入完整的Path,例如/app/v1/order。
前綴匹配:輸入Path的前綴,并且末尾填一個*。例如,匹配所有以/app開頭的請求,那么需設置為/app/*。
正則匹配:正則匹配的語法遵循Google Re2規范。詳細信息,請參見Re2語法。
大小寫敏感:若選中此項,路徑匹配值會區分大小寫。
請求頭(Header):請求訪問的頭部信息,即Header。單擊+請求頭配置,可以配置多個Header,各個Header之間是與的關系。
HeaderKey:Header字段名。
條件:Header支持的匹配條件。
等于:請求Header集合中指定Key的值與輸入值相等。
不等于:請求Header集合中指定Key的值與輸入值不相等。
存在:請求Header集合中存在輸入Key值。
不存在:請求Header集合中不存在輸入Key值。
包含:請求Header集合中指定Key的值包含輸入值。
不包含:請求Header集合中指定Key的值不包含輸入值。
前綴:請求Header集合中指定Key的值以輸入值為前綴。
后綴:請求Header集合中指定Key的值以輸入值為后綴。
正則:請求Header集合中指定Key的值匹配輸入的正則表達式,正則匹配的語法遵循Google Re2規范。詳細信息,請參見Re2語法。
值:Header字段的取值。
復雜條件授權
在授權右側單擊復雜條件。
復雜條件授權支持通過YAML配置Envoy的permission數據結構來配置基于與/或/非組合條件邏輯的授權規則。當滿足配置的條件時執行鑒權邏輯;不滿足條件的請求無需鑒權即可訪問。
返回全局認證鑒權頁面查看鑒權信息,如果已包含新建的網關鑒權信息,說明網關自建認證鑒權新建成功。
查看并管理鑒權服務
登錄MSE網關管理控制臺。
在左側導航欄,選擇云原生網關 > 網關列表,并在頂部菜單欄選擇地域。
在網關列表頁面,單擊目標網關名稱。
在左側導航欄,選擇安全管理 > 全局認證鑒權。
在認證鑒權頁面,單擊目標鑒權規則操作列的詳情,可查看當前服務的基本信息和認證配置,也可查看并管理授權信息。
您可在授權信息區域,單擊創建授權信息。在對話框中輸入請求域名和請求Path,并選擇匹配方式,然后單擊確定新增授權規則。
相關操作
您還可以執行以下其他操作,管理網關的認證鑒權:
開啟鑒權:在全局認證鑒權頁面,單擊目標鑒權規則操作列的開啟,使認證鑒權信息生效。
關閉鑒權:在全局認證鑒權頁面,單擊目標鑒權規則操作列的關閉,關閉網關認證鑒權信息。
編輯鑒權:在全局認證鑒權頁面,單擊目標鑒權規則操作列的編輯,可編輯網關認證鑒權信息。
刪除鑒權:在全局認證鑒權頁面,單擊目標鑒權規則操作列的刪除,可刪除網關認證鑒權信息。
只有在認證鑒權信息關閉的狀態下才可執行刪除操作。
復雜條件授權示例
正則匹配域名示例
本示例中,只對exampleA.com和exampleB.com兩個域名下前綴匹配路徑的請求執行鑒權邏輯。注意此處regex字段配置的正則需要完全匹配,而非部分匹配。
本示例中,test.exampleA.com將無法命中條件,無需鑒權即可訪問。
permissions:
# and_rules 表示下面的所有 rules 條件同時成立時執行鑒權
- and_rules:
rules:
- url_path:
# 前綴匹配路徑
path:
prefix: /
- header:
# 正則匹配
safe_regex_match:
regex: "(exampleA\\.com|exampleB\\.com)"
# 支持HTTP Pseudo-Header規范,可通過":authority"這個Header來獲取域名
name: ":authority"
與/或/非多條件組合示例
本示例滿足以下條件:
exampleA.com/api前綴開頭的請求需要鑒權,但是:
exampleA.com/api/appa/bbb不需要鑒權。
exampleA.com/api/appb/ccc不需要鑒權。
exampleB.com下所有請求需要鑒權,但是:
exampleB.com/api/appa/bbb不需要鑒權。
exampleB.com/api/appb/ccc不需要鑒權。
exampleB.com/api/appc前綴開頭的不需要鑒權,但是:
exampleB.com/api/appc/bbb/ccc需要鑒權。
exampleB.com/api/appc/ccc/ddd需要鑒權。
整理邏輯如下圖所示:
對應的YAML配置如下:
permissions:
# or_rules 表示下面的所有 rules 條件中,有任意一個條件成立時執行鑒權
- or_rules:
rules:
# and_rules,表示下面所有 rules 同時滿足,此 rule 條件才成立
# 規則一
- and_rules:
rules:
- url_path:
path:
exact: /api/appc/bbb/ccc
- header:
exact_match: "exampleB.com"
name: ":authority"
# 規則二
- and_rules:
rules:
- url_path:
path:
exact: /api/appc/ccc/ddd
- header:
exact_match: "exampleB.com"
name: ":authority"
- and_rules:
rules:
# 規則三
- url_path:
path:
prefix: /api/
# not_rule 表示下面的配置不滿足時,此 rule 條件才成立
# 規則四
- not_rule:
url_path:
path:
exact: /api/appa/bbb
# 規則五
- not_rule:
url_path:
path:
exact: /api/appb/ccc
- header:
exact_match: "exampleA.com"
name: ":authority"
- and_rules:
rules:
# 規則六
- url_path:
path:
prefix: /
# not_rule 表示下面的配置不滿足時,此 rule 條件才成立
# 規則七
- not_rule:
url_path:
path:
exact: /api/appa/bbb
# 規則八
- not_rule:
url_path:
path:
exact: /api/appb/ccc
# 規則九
- not_rule:
url_path:
path:
prefix: /api/appc/
- header:
exact_match: "exampleB.com"
name: ":authority"