在Function Compute中,為HTTP觸發器配置JWT認證鑒權,可以確保僅持有有效JWT的用戶端才能訪問函數,從而提升HTTP服務的安全性,有效防止未經授權的訪問和阻擋惡意攻擊。
背景資訊
簡介
Function Compute支援為HTTP觸發器開啟JWT認證鑒權。JWT(JSON Web Token,RFC7519)是一種基於令牌的便捷請求認證鑒權方案。使用者狀態資訊儲存在Token中,由用戶端提供,函數(服務端)無需儲存,是一種Serverless友好的鑒權方式。Function Compute可以通過使用者綁定在HTTP觸發器上的Public JWKS實現對HTTP調用請求的JWT認證。並根據HTTP觸發器上的配置,將claims作為參數轉寄給函數,函數無需對請求進行鑒權,只需關注商務邏輯即可。如果需要瞭解JWT的Token認證流程及基礎知識,請參見基於JWT的token認證和JWT簡介。
JWT認證流程
上圖是Function ComputeHTTP觸發器利用JWT實現認證的整個商務程序時序圖(使用非對稱式加密演算法),步驟詳細解析如下。
用戶端向自訂授權服務發起認證請求,請求中一般會攜帶終端使用者的使用者名稱和密碼。
自訂授權服務讀取請求中的驗證資訊(例如使用者名稱、密碼等)進行驗證,驗證通過之後使用私密金鑰產生標準的Token。
自訂授權服務將攜帶Token的應答返回給用戶端,用戶端需要將這個
Token緩衝到本地。用戶端向HTTP觸發器發送業務請求,請求中攜帶Token。
HTTP觸發器使用使用者佈建的公開金鑰對請求中的Token進行驗證。
驗證通過之後,將請求透傳給受保護的函數。
受保護的函數處理業務請求,並進行應答。
HTTP觸發器將業務應答返回給用戶端。
前提條件
使用限制
可以使用任何方式來產生和分發JWT,Function Compute負責通過觸發器配置的Public JWKS來認證JWT。
支援不含
kid的JWK。支援從
header、Query參數(GET)、表單參數(POST)和cookie中讀取Token。支援將
claims作為header、表單參數(POST)和cookie轉寄給函數。Function Compute支援為一個HTTP觸發器配置一組JWT(JWKS),在JWKS中尋找與
Token中的kid相同的JWK公開金鑰,並使用這個公開金鑰對Token進行簽名校正。一個觸發器的JWKS最多隻允許一個JWK的kid不存在或者為空白字串。目前Function Compute的JWT支援如下演算法。
簽名演算法
alg取值
RSASSA-PKCS1-V1_5
RS256,RS384,RS512
RSASSA-PSS
PS256,PS384,PS512
Elliptic Curve (ECDSA)
ES256,ES384,ES512
HMAC
HS256,HS384,HS512
EdDSA
EdDSA
重要HMAC簽名演算法為對稱式加密,安全性相對較低,建議使用安全性更高的非對稱式加密演算法。
使用非對稱式加密演算法時,出於安全考慮,您的JWT中只需要包含公開金鑰資訊即可,不建議包含私密金鑰資訊。
建議使用HTTPS來對請求中的
Token等敏感資訊進行保護,可以有效避免Token泄漏。
操作步驟
步驟一:配置JWT認證
登入Function Compute控制台,在左側導覽列,選擇。
在頂部功能表列,選擇地區,然後在函數列表頁面,單擊目標函數。
在函數詳情頁面下方,單擊觸發器頁簽,然後單擊HTTP觸發器操作列的編輯。
在編輯觸發程序面板,設定以下配置項,然後單擊確定。
認證方式選擇為JWT 認證。
配置JWKS。
為HTTP觸發器配置JWT鑒權,首先需要提供一個有效JWKS(JSON Web Key Set)。您可以自行產生JWKS,或者搜尋JSON Web Key Generator尋找線上可用的產生工具,例如mkjwk.org。如果您已經有pem格式的密鑰,可以藉助工具(例如jwx),將其轉換為JWKS格式。
本文以使用mkjwk.org工具產生JWKS為例進行示範。如下圖所示,在產生介面,Key Use選擇Signature、Algorithm選擇RS256、Show X.509選擇Yes,然後單擊Generate。在您的代碼中需要使用Private Key(下圖中①)簽發JWT Token,請妥善保管。您可以複製Public Key(下圖中②)的內容填入控制台中的JWKS配置的keys數組中。


本文配置的JWKS樣本如下。
{ "keys": [ { "alg": "RS256", "e": "AQAB", "kty": "RSA", "n": "u1LWgoomekdOMfB1lEe96OHehd4XRNCbZRm96RqwOYTTc28Sc_U5wKV2umDzolfoI682ct2BNnRRahYgZPhbOCzHYM6i8sRXjz9Ghx3QHw9zrYACtArwQxrTFiejbfzDPGdPrMQg7T8wjtLtkSyDmCzeXpbIdwmxuLyt_ahLfHelr94kEksMDa42V4Fi5bMW4cCLjlEKzBEHGmFdT8UbLPCvpgsM84JK63e5ifdeI9NdadbC8ZMiR--dFCujT7AgRRyMzxgdn2l-nZJ2ZaYzbLUtAW5_U2kfRVkDNa8d1g__2V5zjU6nfLJ1S2MoXMgRgDPeHpEehZVu2kNaSFvDUQ", "use": "sig" } ] }在JWT Token 配置配置項中,選擇
Token所在位置和Token的名稱。Token位置支援Header、Cookie、Query參數(GET)和表單參數(POST)。如果Token位置選擇為Header,則還需為其指定參數名稱和去除首碼。Function Compute在擷取Token時,會刪除去除首碼中設定的首碼內容。
在JWT Claim 轉換配置項中,選擇透傳給函數的參數所在位置、參數原始名稱和參數透傳給函數之後的名稱。
映射參數位置支援Header、Cookie和表單參數(POST)。

佈建要求匹配模式。
匹配全部:所有HTTP請求都需要進行JWT校正。
白名單模式:請求路徑白名單中設定的Path的HTTP請求不需要JWT校正,其他請求需要JWT校正。
黑名單模式:請求路徑黑名單中設定的Path的HTTP請求需要JWT校正,其他請求不需要JWT校正。
白名單模式和黑名單模式支援以下兩種匹配方式:
精確匹配
請求的路徑和設定的路徑完全一致才可以匹配。例如,設定請求路徑黑名單為/a,則來自路徑/a的請求需要JWT校正,來自路徑/a/的請求無需校正。
模糊比對
支援使用萬用字元(*)設定路徑,且萬用字元(*)只能放到路徑的最後。例如,設定請求路徑黑名單為/login/*,則來自路徑首碼為/login/(例如/login/a、/login/b/c/d)的請求均需要JWT校正。
步驟二:操作驗證
在調測工具(本文以Postman工具為例)中,根據HTTP觸發器的JWT配置,填寫訪問地址、Token等,驗證是否可以正常訪問HTTP服務。
使用步驟一:配置JWT認證中產生的X.509 PEM格式的Private Key作為私密金鑰來頒發JWT Token。以下步驟以Python為例示範通過本地指令碼產生Token的過程。
安裝 PyJWT模組。
pip install 'PyJWT>=2.0'在本地運行如下Python樣本指令碼產生JWT Token。
import jwt import time private_key = """ -----BEGIN PRIVATE KEY----- <使用步驟一產生的 X.509 PEM格式的private key> -----END PRIVATE KEY----- """ headers = { "alg": "RS256", "typ": "JWT" } payload = { "sub": "1234567890", "name": "John Snow", "iat": int(time.time()), # token頒發時間 "exp": int(time.time()) + 60 * 60, # 設定token有效時間為1小時 } encoded = jwt.encode(payload=payload, key=private_key.encode(), headers=headers) print("Generated token: %s" % encoded)
使用Postman工具驗證HTTP服務是否可正常訪問。
在目標函數詳情頁面的觸發器頁簽擷取HTTP觸發器的公網訪問地址,將地址填入Postman的URL位置。
在Postman的Headers配置Token參數資訊,然後單擊Send發送請求。本文填寫的Token樣本如下。
名稱
值
說明
Key
Authentication在JWT Token 配置中設定的參數名稱。
Value
Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoiSm9uIFNub3ciLCJhZG1pbiI6dHJ1ZSwiZXhwIjo0ODI5NTk3NjQxfQ.eRcobbpjAd3OSMxcWbmbicOTLjO2vuLR9F2QZMK4rz1JqfSRHgwQVqNxcfOIO9ckDMNlF_3jtdfCfvXfka-phJZpHmnaQJxmnOA8zA3R4wF4GUQdz5zkt74cK9jLAXpokwrviz2ROehwxTCwa0naRd_N9eFhvTRnP3u7L0xn3ll4iOf8Q4jS0mVLpjyTa5WiBkN5xi9hkFxd__p98Pah_Yf0hVQ2ldGSyTtAMmdM1Bvzad-kdZ_wW0jcctIla9bLnOo-Enr14EsGvziMh_QTZ3HQtJuToSKZ11xkNgaz7an5de6PuF5ISXQzxigpFVIkG765aEDVtEnFkMO0xyPGLg在JWT Token 配置中設定的去除首碼資訊拼接JWT Token。樣本值假設去除首碼已設定為
Bearer。重要請注意,請求header中JWT參數的首碼和空格需要與JWT Token 配置中設定的去除首碼內容一致,否則會導致觸發器解析Token時出錯並返回invalid or expired jwt錯誤。