在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
、Query
參數(GET)、表單參數(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。在您的代碼中需要使用Private Key簽發JWT Token,複製Public Key中的內容填入控制台中的JWKS輸入框。
本文配置的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時,會刪除去除首碼中設定的首碼內容。重要設定去除首碼時,請注意首碼後面是否存在空格。推薦在首碼欄位後加一個空格,例如
Bearer
。在JWT Claim 轉換配置項中,選擇透傳給函數的參數所在位置、參數原始名稱和參數透傳給函數之後的名稱。
映射參數位置支援Header、Cookie、Query參數(GET)和表單參數(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
在本地運行如下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錯誤。