在Service Mesh中配置JWT(JSON Web Token)請求授權,可以實現來源認證,又稱為終端使用者認證。在接收使用者請求時,該配置用於認證要求標頭資訊中的Access Token是否可信,並授權給來源合法的請求。本文介紹如何在ASM中對入口網關進行JWT請求鑒權,使之通過入口網關訪問服務時,必須帶有可信的Access Token。
前提條件
已添加叢集到ASM執行個體。具體操作,請參見添加叢集到ASM執行個體。
已部署入口網關。具體操作,請參見建立入口網關。
背景資訊
本文以httpbin服務為例,使用請求身份認證對通過入口網關訪問服務的請求進行限制,實現只有帶有正確的JWT Token才能訪問服務成功,錯誤的JWT Token將訪問服務失敗,但是不帶有JWT Token也能訪問服務成功。在此基礎上,您可以使用授權策略對請求進行進一步限制,分為兩個情境:
使用授權策略,使之請求必須帶有JWT Token,才能通過入口網關訪問服務成功。
使用授權策略,使之請求必須帶有固定頒發者的JWT Token,才能通過入口網關訪問服務成功。
步驟一:部署樣本服務
為default命名空間開啟自動注入。
登入ASM控制台。
在左側導覽列,選擇 。
在網格詳情頁面左側導覽列,選擇 。
在全域命名空間頁面,單擊default右側自動注入列下的啟用 Sidecar 網格代理自動注入。
在確認對話方塊單擊確定。
部署樣本服務。
使用以下內容,建立httpbin.yaml。
apiVersion: v1 kind: ServiceAccount metadata: name: httpbin --- apiVersion: v1 kind: Service metadata: name: httpbin labels: app: httpbin service: httpbin spec: ports: - name: http port: 8000 targetPort: 80 selector: app: httpbin --- apiVersion: apps/v1 kind: Deployment metadata: name: httpbin spec: replicas: 1 selector: matchLabels: app: httpbin version: v1 template: metadata: labels: app: httpbin version: v1 spec: serviceAccountName: httpbin containers: - image: docker.io/kennethreitz/httpbin imagePullPolicy: IfNotPresent name: httpbin ports: - containerPort: 80
執行以下命令,建立httpbin應用。
kubectl apply -f httpbin.yaml -n default
步驟二:建立網關規則和虛擬服務
建立網關規則。
登入ASM控制台,在左側導覽列,選擇 。
在網格管理頁面,單擊目標執行個體名稱,然後在左側導覽列,選擇 ,然後單擊使用YAML建立。
設定命名空間為default,輸入以下內容到文字框,然後單擊建立。
apiVersion: networking.istio.io/v1beta1 kind: Gateway metadata: name: httpbin-gateway namespace: default spec: selector: istio: ingressgateway servers: - hosts: - '*' port: name: http number: 80 protocol: HTTP
建立虛擬服務。
在網格詳情頁面左側導覽列,選擇 ,然後在右側頁面,單擊使用YAML建立。
設定命名空間為default,輸入以下內容到文字框,然後單擊建立。
apiVersion: networking.istio.io/v1beta1 kind: VirtualService metadata: name: httpbin namespace: default spec: gateways: - httpbin-gateway hosts: - '*' http: - route: - destination: host: httpbin port: number: 8000
步驟三:建立請求身份認證
建立JWK。
在openssl中執行以下命令,產生2048位的RSA私密金鑰。
openssl genrsa -out rsa-private-key.pem 2048
執行以下命令,通過私密金鑰產生公開金鑰。
openssl rsa -in rsa-private-key.pem -pubout -out rsa-public-key.pem
在JWK to PEM Convertor online工具中選中PEM-to-JWK (RSA Only),輸入公開金鑰,單擊submit,將公開金鑰轉化為JWK。
{"kty":"RSA","e":"AQAB","kid":"59399e22-7a9a-45ed-8c76-7add7863915c","n":"2dnwOlDKEwII9Cyh9w7o59a5y3RS2gWUKYC3HSBJL1FhYIZa7sjTCKxwEuG-vCRQkR6augWxYWseSDfgtyivzi3CxxkF8WnQbECOCGm5xAYKmMcXeOpv0zsJTHN122Tt_tsd6K2OC3yGwKtmp7m-MOpHagqWRqFtvyEOm_1JW1-t0n1VsGSeWww8dvcmnJPKAKHbAU40jdV1hMn9AA3RfSpDY6nfrUkpXA5-aQ6rJRjMn36DatZ5ykVL4LKPOUxZdfK_yNIPkCnwIKesqiOpr4s-iCM8pMiZuejDZ1qoX-uBjggESf4G9_L-laDSeoDmXeOZ9kzN3Jw8ay69ihIFEQ"}
建立請求身份認證。
登入ASM控制台。
在左側導覽列,選擇 。
在網格管理頁面,找到待配置的執行個體,單擊執行個體的名稱或在操作列中單擊管理。
在網格詳情頁面左側導覽列選擇 ,然後在右側頁面單擊建立。
在建立頁面配置相關資訊,然後單擊建立。
配置項
描述
命名空間
設定命名空間為istio-system。
名稱
輸入名稱。
匹配標籤
匹配標籤用於匹配請求身份認證生效的服務。
單擊新增匹配標籤,設定名稱為istio,值為ingressgateway。
jwt規則集
單擊jwt規則集右側的添加,設定JWT規則:
issuer:JWT的頒發者,本文設定為testing@asm.test.io。
audiences:JWT受眾列表。設定哪些服務可以使用JWT Token訪問目標服務。本文設定為空白,表示對訪問的服務不受限制。
jwks:設定JWT資訊,本文設定為
{"keys":[步驟1建立的JWK]}
,例如步驟1建立的JWK為{"kty":"RSA","e":"AQAB","kid":"59399e22-7a9a-45ed-8c76-7add786****"}
,則jwks為{"keys":[{"kty":"RSA","e":"AQAB","kid":"59399e22-7a9a-45ed-8c76-7add786****"}]}
。
步驟四:驗證請求身份認證是否生效
使用JWT工具將JWT請求資訊編碼成JWT Token。
在Decoded地區輸入以下JWT請求資訊,在Encode地區將自動轉換成JWT Token。
HEADRE:設定密碼編譯演算法為RS256,輸入JWK中的kid,設定類型為JWT。
PAYLOAD:設定iss為testing@asm.test.io,您還可以添加自訂的額外資訊。
VERIFY SIGNATURE:輸入步驟1的建立的公開金鑰和私密金鑰。
通過入口網關訪問服務。
執行以下命令,帶有步驟1建立的JWT Token的請求訪問服務。
curl -I -H "Authorization: Bearer $TOKEN" http://{您的ASM網關地址}/
預期輸出:
HTTP/1.1 200 OK server: istio-envoy date: Fri, 18 Mar 2022 07:27:54 GMT
執行以下命令,帶有無效的JWT Token的請求訪問服務。
curl -I -H "Authorization: Bearer invalidToken" http://{您的ASM網關地址}/
預期輸出:
HTTP/1.1 401 Unauthorized www-authenticate: Bearer realm="http://47.98.25*.***/", error="invalid_token" content-length: 79 content-type: text/plain date: Fri, 18 Mar 2022 07:59:00 GMT server: istio-envoy
執行以下命令,不帶有JWT Token的請求訪問服務。
curl -I http://{您的ASM網關地址}/
預期輸出:
HTTP/1.1 200 OK server: istio-envoy date: Fri, 18 Mar 2022 07:27:54 GMT
根據以上結果,可以看到帶有正確的JWT Token或不帶有JWT Token的請求訪問服務成功,帶有錯誤的JWT Token的請求訪問服務失敗,說明請求身份認證生效。
步驟五:建立授權策略
情境一:使用授權策略對訪問服務的請求進行限制
建立授權策略,使之請求必須帶有JWT Token,才能通過入口網關訪問服務。
登入ASM控制台。
在左側導覽列,選擇 。
在網格管理頁面,找到待配置的執行個體,單擊執行個體的名稱或在操作列中單擊管理。
在網格詳情頁面左側導覽列,選擇 ,然後在右側頁面,單擊建立。
在建立頁面配置相關資訊,然後單擊建立。
配置項
說明
名稱
輸入授權策略的名稱。
策略類型
設定策略類型為允許。
網關生效
單擊網關生效頁簽,設定ASM網關為ingressgateway。在添加請求來源地區,開啟請求JWT主體(RequestPrincipals)開關,在對應文字框中輸入*。
驗證使用授權策略對訪問服務的請求進行限制是否成功。
執行以下命令,不帶有JWT Token的請求訪問服務。
curl -I http://{您的ASM網關地址}/
預期輸出:
HTTP/1.1 401 Unauthorized www-authenticate: Bearer realm="http://47.98.25*.***/", error="invalid_token" content-length: 79 content-type: text/plain date: Fri, 18 Mar 2022 07:59:00 GMT server: istio-envoy
執行以下命令,使用帶有JWT Token的請求訪問服務。
curl -I -H "Authorization: Bearer $TOKEN" http://{您的ASM網關地址}/
預期輸出:
HTTP/1.1 200 OK server: istio-envoy date: Fri, 18 Mar 2022 07:27:54 GMT
可以看到不帶有JWT Token的請求訪問服務失敗,帶有JWT Token的請求訪問服務成功,說明使用授權策略對訪問服務的請求進行限制成功。
情境二:使用授權策略對訪問服務的請求的JWT Token頒發者進行限制
建立授權策略,使之請求必須帶有頒發者為testing@asm.test.io的JWT Token,才能通過入口網關訪問服務。
登入ASM控制台。
在左側導覽列,選擇 。
在網格管理頁面,找到待配置的執行個體,單擊執行個體的名稱或在操作列中單擊管理。
在網格詳情頁面左側導覽列,選擇 ,然後在右側頁面,單擊建立。
在建立頁面配置相關資訊,然後單擊建立。
配置項
說明
名稱
輸入授權策略的名稱。
策略類型
設定策略類型為允許。
網關生效
單擊網關生效頁簽,設定ASM網關為ingressgateway。在添加請求來源地區,開啟請求JWT主體(RequestPrincipals)開關,在對應文字框中輸入testing@asm.test.io/demo@asm.test.io。
驗證使用授權策略對訪問服務的請求的頒發者進行限制是否成功。
執行以下命令,使用帶有JWT Token的請求訪問服務。
curl -I -H "Authorization: Bearer $TOKEN" http://{您的ASM網關地址}/
預期輸出:
HTTP/1.1 401 Unauthorized www-authenticate: Bearer realm="http://47.98.25*.***/", error="invalid_token" content-length: 79 content-type: text/plain date: Fri, 18 Mar 2022 07:59:00 GMT server: istio-envoy
授權策略限制了訪問服務的請求的JWT Token的頒發者必須為testing@asm.test.io/demo@asm.test.io,所以帶有頒發者為testing@asm.test.io的JWT Token請求訪問失敗。
修改JWT Token的頒發者為testing@asm.test.io/demo@asm.test.io。
執行以下命令,使用上文產生JWT Token的請求訪問服務。
curl -I -H "Authorization: Bearer $TOKEN" http://{您的ASM網關地址}/
預期輸出:
HTTP/1.1 200 OK server: istio-envoy date: Fri, 18 Mar 2022 07:27:54 GMT
帶有頒發者為testing@asm.test.io/demo@asm.test.io的JWT Token請求訪問服務成功,說明使用授權策略對訪問服務的請求的JWT Token頒發者進行限制成功。