全部產品
Search
文件中心

Alibaba Cloud Service Mesh:開發基於HTTP協議的自訂授權服務

更新時間:Sep 04, 2024

Service Mesh (ASM)支援完善的認證、授權配置,還提供了靈活的擴充能力,支援對接HTTP協議和gRPC協議的自訂授權服務,並接入網格的鑒權流程。本文介紹如何開發一個基於HTTP協議的自訂授權服務。

背景資訊

通過服務網格,您可以在網關上配置JWT認證(RequestAuthentication)完成對請求身份的認證;對於網格內的請求,預設通過網格提供的mTLS認證完成請求身份的認證。確認了請求身份之後,您可以通過授權策略(AuthorizationPolicy)限制請求的行為。在提供了上述標準能力的同時,服務網格還支援接入自訂授權服務。自訂授權服務的整體流程大致如下。

當您配置使用HTTP協議對接自訂授權服務時,網格代理(網關或Sidecar)會將收到的請求資訊填充到HTTP協議的鑒權請求中,然後發往自訂授權服務,由自訂授權服務判斷是否允許存取該請求。

  • 自訂授權服務返回200表示通過驗證,需要允許存取請求。

  • 自訂授權服務返回5xx代表授權服務異常,需要根據配置決定允許存取或拒絕請求。

  • 其他狀態代碼均會被視為驗證不通過,需要拒絕該請求。

配置介紹

ASM支援使用介面關聯一個自訂授權服務,關聯之後您可以在授權策略中配置要使用鑒權服務的網格代理。具體操作,請參見使用HTTP協議對接自訂授權服務

開發HTTP自訂授權服務

ASM相容開源Istio服務網格,Istio社區提供了自訂授權服務的開發樣本。這部分代碼同時實現了HTTP和gRPC兩種協議的自訂授權服務。本文涉及的HTTP部分主要邏輯在ServeHTTP函數中:

// ServeHTTP implements the HTTP check request.
func (s *ExtAuthzServer) ServeHTTP(response http.ResponseWriter, request *http.Request) {
	body, err := io.ReadAll(request.Body)
	if err != nil {
		log.Printf("[HTTP] read body failed: %v", err)
	}
	l := fmt.Sprintf("%s %s%s, headers: %v, body: [%s]\n", request.Method, request.Host, request.URL, request.Header, returnIfNotTooLong(string(body)))
	if allowedValue == request.Header.Get(checkHeader) {
		log.Printf("[HTTP][allowed]: %s", l)
		response.Header().Set(resultHeader, resultAllowed)
		response.Header().Set(overrideHeader, request.Header.Get(overrideHeader))
		response.Header().Set(receivedHeader, l)
		response.WriteHeader(http.StatusOK)
	} else {
		log.Printf("[HTTP][denied]: %s", l)
		response.Header().Set(resultHeader, resultDenied)
		response.Header().Set(overrideHeader, request.Header.Get(overrideHeader))
		response.Header().Set(receivedHeader, l)
		response.WriteHeader(http.StatusForbidden)
		_, _ = response.Write([]byte(denyBody))
	}
}

可以看出,此函數對請求的header進行了判斷。如果header的值是allowedValue就返回200(允許通過),其他情況返回403(不允許通過)。

配置自訂授權服務

在ACK叢集中部署上一步開發的自訂授權服務後,您可以開始自訂授權服務的接入。具體操作,請參見接入HTTP協議的自訂授權服務

重要

由於此授權服務中用到了checkHeader這個變數對應的header,所以您需要在網格中匯入自訂授權服務時配置在鑒權請求中攜帶header配置項,否則無法擷取到對應的返回結果。