全部產品
Search
文件中心

Alibaba Cloud Service Mesh:ASM中整合Keycloak實現網格內應用單點登入

更新時間:Jun 30, 2024

本文介紹如何使用自建的Keycloak作為IdP來提供身份服務,實現網格內應用的單點登入。網格內應用無需實現認證、鑒權邏輯,通過配置ASM的自訂授權服務,即可通過OIDC協議使用Keycloak完成單點登入。鑒權通過後,請求將攜帶Keycloak中的使用者資訊一同發往應用。

前提條件

相關概念

概念

說明

IdP

Identity Provider的縮寫,身份供應商。例如,您可以通過帳號+密碼的形式來驗證您的身份。當您使用支付寶帳號登入優酷,這個情境中支付寶即為IdP。

OIDC

OIDC是OpenID Connect的簡稱,是一個基於OAuth 2.0協議的身份認證標準協議。更多資訊,請參見OpenID Connect

Scope

OIDC中的概念,每一個IdP同時也儲存了使用者的各種資訊,例如Email、設定檔等,這些分類被稱為Scope。在通過IdP進行Authentication(登入操作)時,一些IdP會要求選擇允許訪問使用者的哪些資料,每一個類別都對應一個Scope。

操作步驟

步驟一: 部署示範應用和Keycloak

  1. 參照下方YAML,使用kubectl apply -n default -f xxx.yaml命令,將Httpbin應用部署至ACK叢集的default命名空間。

    展開查看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
  2. 參照下方YAML,使用kubectl apply -n default -f xxx.yaml命令,將Keycloak應用部署至ACK叢集的default命名空間。

    展開查看YAML

    apiVersion: v1
    kind: Service
    metadata:
      name: keycloak
      labels:
        app: keycloak
    spec:
      ports:
      - name: http
        port: 8080
        targetPort: 8080
      selector:
        app: keycloak
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: keycloak
      labels:
        app: keycloak
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: keycloak
      template:
        metadata:
          labels:
            app: keycloak
        spec:
          containers:
          - name: keycloak
            image: quay.io/keycloak/keycloak:latest
            args: ["start-dev"]
            env:
            - name: KEYCLOAK_ADMIN
              value: "admin"
            - name: KEYCLOAK_ADMIN_PASSWORD
              value: "admin"
            - name: KC_PROXY
              value: "edge"
            ports:
            - name: http
              containerPort: 8080
            readinessProbe:
              httpGet:
                path: /realms/master
                port: 8080

步驟二:將示範應用和Keycloak通過ASM網關暴露至公網

本文樣本使用HTTPS(連接埠:443)訪問示範應用,使用HTTP(連接埠:80)訪問Keycloak控制台。

  1. 為HTTPS服務建立認證,命名為myexample-credential。更多內容,請參見通過ASM網關啟用HTTPS安全服務

  2. 使用如下YAML在ASM叢集建立網關規則和虛擬服務,將Keycloak露出在公網。

    1. 使用如下YAML,在ASM控制台配置網關規則至對應的ASM執行個體。具體操作,請參見管理網關規則

      展開查看YAML

      apiVersion: networking.istio.io/v1beta1
      kind: Gateway
      metadata:
        name: ingressgateway
        namespace: istio-system
      spec:
        selector:
          app: istio-ingressgateway //需要確認該selector和當前已存在的網關是匹配的。
        servers:
          - hosts:
              - '*'
            port:
              name: http-httpbin //使用HTTPS(443連接埠)訪問樣本應用。
              number: 443
              protocol: HTTPS
            tls:
              credentialName: myexample-credential
              mode: SIMPLE
          - hosts:
              - '*'
            port:
              name: keycloak //使用HTTP(80連接埠)訪問keycloak控制台。
              number: 80
              protocol: HTTP
                                      
    2. 使用如下YAML,將如下虛擬服務應用到ASM執行個體。具體操作,請參見管理虛擬服務

      展開查看YAML

      apiVersion: networking.istio.io/v1beta1
      kind: VirtualService
      metadata:
        name: ingressgateway-vs
        namespace: istio-system
      spec:
        gateways:
          - ingressgateway
        hosts:
          - '*'
        http:
          - match:
              - port: 80
            name: keycloak
            route:
              - destination:
                  host: keycloak.default.svc.cluster.local
                  port:
                    number: 8080
          - name: httpbin
            route:
              - destination:
                  host: httpbin.default.svc.cluster.local
                  port:
                    number: 8000
  3. 使用http://${入口網關地址}在瀏覽器訪問Keycloak應用。3

  4. 單擊Administration Console,使用部署Keycloak時指定的Admin和PassWord進行登入。

步驟三:配置Keycloak

  1. 在Keycloak左側導覽列,在Master下拉式清單中單擊Create Realm2

  2. 在建立Realm配置導航頁面,如下圖所示,建立新的Client。43

  3. 建立完成後,在Realm頁面,按照下圖,建立User。單擊Save4

  4. User details頁面,單擊Credentials

  5. 在彈出的對話方塊,設定登入密碼。單擊Save設定登入密碼

  6. 參照下圖,建立一個Realm Role。單擊SaveRole

  7. User details頁面,選擇Role mapping

  8. Role mapping頁面,單擊Assign role。將步驟六建立的Role分配給目前使用者。5

  9. 參照下圖,建立Client Scope。單擊Save建立ClientScope

  10. Client Scope頁面,單擊mappers,參照下圖,添加一個Mapper。單擊Save13

  11. 單擊scope,選中步驟六建立的Role左側的複選框,單擊Assign8

  12. 在Client設定介面,單擊client scope,以default方式添加client scope。9

  13. 按照下圖,添加叢集oauth2-proxy的Valid redirect URls。單擊Save10

說明

該操作步驟的樣本裡只有Keycloak服務使用HTTP協議,其餘服務均使用HTTPS。所以redirect URI的格式為:https://${您的ASM網關地址}/oauth2/callback

至此,Keycloak已經全部設定好。您需要記錄以下資訊:

  • 建立Realm的ID:Test-oidc

  • Realm中建立的Client ID:oauth2proxy

  • Client設定中,Credentials子選項卡中的client secret

步驟四:啟用ASM自訂授權,配置OIDC單點登入

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

  2. 網格管理頁面,單擊目標執行個體名稱,然後在左側導覽列,選擇網格資訊安全中心 > 自訂授權服務

  3. 自訂授權服務頁面,單擊關聯自訂授權服務,選擇OIDC身份認證授權服務。設定OIDC身份認證授權服務參數,單擊建立

    關聯外部授權服務

    請您根據之前建立的OIDC應用的相關資訊,填寫如上圖中的欄位,您可以使用ASM網關作為登入重新導向地址。更多關於Cookie Secret,請參見Cookie Secret的產生

    • IdP OIDC Issuer URLhttp://${ASM網關地址}/realms/${keycloak中建立的realm}

    • ClientIDClient Secret:使用上一步驟中記錄的參數。

    • Scopes:該參數中的OpenID為必填項,請您根據實際情況進行填寫。

  4. 參照如下樣本,建立VirtualService。

    apiVersion: networking.istio.io/v1beta1
    kind: VirtualService
    metadata:
      name: oauth2-vs
      namespace: istio-system
    spec:
      gateways:
        - ingressgateway
      hosts:
        - '*'
      http:
        - match:
            - uri:
                prefix: /oauth2
          name: oauth2
          route:
            - destination:
                host: asm-oauth2proxy-httpextauth-oidc.istio-system.svc.cluster.local
                port:
                  number: 4180
    說明
    • route欄位的host請您替換為您的ACK叢集中istio-system namespace下對應的Oauth2Proxy的Service名稱。

    • 為防止VirtualService衝突,請避免其他VirtualService匹配首碼為《/oauth2》的路徑。

步驟五:建立授權策略

  1. 網格管理頁面,單擊目標執行個體名稱,然後在左側導覽列,選擇網格資訊安全中心 > 授權策略

  2. 在授權策略詳情頁面,單擊使用YAML建立

  3. 建立頁面,選擇命名空間情境模版,配置如下YAML檔案,然後單擊建立

    apiVersion: security.istio.io/v1beta1
    kind: AuthorizationPolicy
    metadata:
      name: oidc
      namespace: istio-system
    spec:
      action: CUSTOM
      provider:
        name: httpextauth-oidc
      rules:
        - to:
            - operation:
                notPorts:
                  - '80'
      selector:
        matchLabels:
          istio: ingressgateway
    說明
    • AuthorizationPolicy指定了訪問除了80以外的其它連接埠,均需要進行授權。

    • provider name填寫您關聯的自訂授權服務的名稱,您可以在自訂授權服務的列表中進行尋找。

步驟六:驗證

  1. 在瀏覽器中訪問${ASM網關外部IP:80}

    預期結果:1若您可以看到如上頁面,則證明單點登入已經生效。

  2. 單擊Sign in with OpenID Connect,在Keycloak的登入頁面,請輸入您在步驟一中建立的測試帳號以及密碼,單擊登入

    預期結果:httpbin

  3. 單擊Request inspection,選擇/headers > try it out > Execute

    預期結果:11

  4. 請將上一步驟中Bearer之後請求攜帶的JWT在JWT Debugger中進行解析。更多關於JWT Debugger的內容,請參見JWT debugger

    預期結果:JWT解析成功後,您可以看到如下資訊。其中附帶Keycloak中儲存的使用者資訊,並且當前的JWT已經經過了ASM的校正。