全部產品
Search
文件中心

Alibaba Cloud Service Mesh:在ASM中對入口網關進行JWT請求鑒權

更新時間:Jun 30, 2024

Service Mesh中配置JWT(JSON Web Token)請求授權,可以實現來源認證,又稱為終端使用者認證。在接收使用者請求時,該配置用於認證要求標頭資訊中的Access Token是否可信,並授權給來源合法的請求。本文介紹如何在ASM中對入口網關進行JWT請求鑒權,使之通過入口網關訪問服務時,必須帶有可信的Access Token。

前提條件

背景資訊

本文以httpbin服務為例,使用請求身份認證對通過入口網關訪問服務的請求進行限制,實現只有帶有正確的JWT Token才能訪問服務成功,錯誤的JWT Token將訪問服務失敗,但是不帶有JWT Token也能訪問服務成功。在此基礎上,您可以使用授權策略對請求進行進一步限制,分為兩個情境:

  • 使用授權策略,使之請求必須帶有JWT Token,才能通過入口網關訪問服務成功。

  • 使用授權策略,使之請求必須帶有固定頒發者的JWT Token,才能通過入口網關訪問服務成功。

步驟一:部署樣本服務

  1. 為default命名空間開啟自動注入。

    1. 登入ASM控制台

    2. 在左側導覽列,選擇服務網格 > 網格管理

    3. 在網格詳情頁面左側導覽列,選擇網格執行個體 > 全域命名空間

    4. 全域命名空間頁面,單擊default右側自動注入列下的啟用 Sidecar 網格代理自動注入

    5. 確認對話方塊單擊確定

  2. 部署樣本服務。

    1. 擷取叢集KubeConfig並通過kubectl工具串連叢集

    2. 使用以下內容,建立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
    3. 執行以下命令,建立httpbin應用。

      kubectl apply -f httpbin.yaml -n default

步驟二:建立網關規則和虛擬服務

  1. 建立網關規則。

    1. 登入ASM控制台,在左側導覽列,選擇服務網格 > 網格管理

    2. 網格管理頁面,單擊目標執行個體名稱,然後在左側導覽列,選擇ASM網關 > 網關規則,然後單擊使用YAML建立

    3. 設定命名空間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
  2. 建立虛擬服務。

    1. 在網格詳情頁面左側導覽列,選擇流量管理中心 > 虛擬服務,然後在右側頁面,單擊使用YAML建立

    2. 設定命名空間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

步驟三:建立請求身份認證

  1. 建立JWK。

    1. openssl中執行以下命令,產生2048位的RSA私密金鑰。

      openssl genrsa -out rsa-private-key.pem 2048
    2. 執行以下命令,通過私密金鑰產生公開金鑰。

      openssl rsa -in rsa-private-key.pem -pubout -out rsa-public-key.pem
    3. 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"}
  2. 建立請求身份認證。

    1. 登入ASM控制台

    2. 在左側導覽列,選擇服務網格 > 網格管理

    3. 網格管理頁面,找到待配置的執行個體,單擊執行個體的名稱或在操作列中單擊管理

    4. 在網格詳情頁面左側導覽列選擇網格資訊安全中心 > 請求身份認證,然後在右側頁面單擊建立

    5. 建立頁面配置相關資訊,然後單擊建立

      請求身份認證

      配置項

      描述

      命名空間

      設定命名空間istio-system

      名稱

      輸入名稱。

      匹配標籤

      匹配標籤用於匹配請求身份認證生效的服務。

      單擊新增匹配標籤,設定名稱istioingressgateway

      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****"}]}

步驟四:驗證請求身份認證是否生效

  1. 使用JWT工具將JWT請求資訊編碼成JWT Token。

    Decoded地區輸入以下JWT請求資訊,在Encode地區將自動轉換成JWT Token。

    • HEADRE:設定密碼編譯演算法為RS256,輸入JWK中的kid,設定類型為JWT。

    • PAYLOAD:設定iss為testing@asm.test.io,您還可以添加自訂的額外資訊。

    • VERIFY SIGNATURE:輸入步驟1的建立的公開金鑰和私密金鑰。

    JWT

  2. 通過入口網關訪問服務。

    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
    2. 執行以下命令,帶有無效的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
    3. 執行以下命令,不帶有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,才能通過入口網關訪問服務。

  1. 登入ASM控制台

  2. 在左側導覽列,選擇服務網格 > 網格管理

  3. 網格管理頁面,找到待配置的執行個體,單擊執行個體的名稱或在操作列中單擊管理

  4. 在網格詳情頁面左側導覽列,選擇網格資訊安全中心 > 授權策略,然後在右側頁面,單擊建立

  5. 建立頁面配置相關資訊,然後單擊建立

    授權策略

    配置項

    說明

    名稱

    輸入授權策略的名稱。

    策略類型

    設定策略類型允許

    網關生效

    單擊網關生效頁簽,設定ASM網關ingressgateway。在添加請求來源地區,開啟請求JWT主體(RequestPrincipals)開關,在對應文字框中輸入*

  6. 驗證使用授權策略對訪問服務的請求進行限制是否成功。

    1. 執行以下命令,不帶有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
    2. 執行以下命令,使用帶有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,才能通過入口網關訪問服務。

  1. 登入ASM控制台

  2. 在左側導覽列,選擇服務網格 > 網格管理

  3. 網格管理頁面,找到待配置的執行個體,單擊執行個體的名稱或在操作列中單擊管理

  4. 在網格詳情頁面左側導覽列,選擇網格資訊安全中心 > 授權策略,然後在右側頁面,單擊建立

  5. 建立頁面配置相關資訊,然後單擊建立

    授權策略情境二

    配置項

    說明

    名稱

    輸入授權策略的名稱。

    策略類型

    設定策略類型允許

    網關生效

    單擊網關生效頁簽,設定ASM網關ingressgateway。在添加請求來源地區,開啟請求JWT主體(RequestPrincipals)開關,在對應文字框中輸入testing@asm.test.io/demo@asm.test.io

  6. 驗證使用授權策略對訪問服務的請求的頒發者進行限制是否成功。

    1. 執行以下命令,使用帶有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請求訪問失敗。

    2. 修改JWT Token的頒發者為testing@asm.test.io/demo@asm.test.io。

      JWT工具中PAYLOAD中設定iss為testing@asm.test.io,sub為demo@asm.test.io。其他配置和步驟1保持相同。jwt2

    3. 執行以下命令,使用上文產生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頒發者進行限制成功。