全部产品
Search
文档中心

服务网格 ASM:ASM中集成Keycloak实现网格内应用单点登录

更新时间:Jun 16, 2026

本文介绍如何使用自建的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应用。

  4. 单击Administration Console,使用部署Keycloak时指定的Admin和PassWord进行登录。

步骤三:配置Keycloak

  1. 在Keycloak左侧导航栏,在Master下拉列表中单击Create Realm

  2. 在新建Realm配置导航页面创建新的Client。在General Settings页签中,Client type选择OpenID ConnectClient ID设置为oauth2proxy。在Capability config页签中,开启Client authentication,关闭AuthorizationAuthentication flow仅勾选Standard flowDirect access grants

  3. 创建完成后,在Realm页面创建User。单击Save。其中Username设置为asm-test,并开启Email verified

  4. User details页面,单击Credentials

  5. 在弹出的对话框,设置登录密码。单击Save。其中将Temporary设置为Off

  6. 创建一个Realm Role。单击Save。其中Role name设置为test-role

  7. User details页面,选择Role mapping

  8. Role mapping页面,单击Assign role。将步骤六创建的Role分配给当前用户。

  9. 创建Client Scope。单击Save。其中Name设置为test_scopeProtocol选择OpenID Connect,开启Display on consent screenInclude in token scope

  10. Client Scope页面,单击mappers添加一个Mapper。单击Save。其中Mapper type选择AudienceName设置为test-mapperIncluded Client Audience选择oauth2proxy,开启Add to access token

  11. 单击scope,选中步骤六创建的Role左侧的复选框,单击Assign

  12. 在Client设置界面,单击client scope,以default方式添加client scope。

  13. 添加集群oauth2-proxy的Valid redirect URls。单击Save。在Settings页签的Access settings区域,在Valid redirect URIs中填入https://${ASM网关地址}/oauth2/callback

说明

该操作步骤的示例里只有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身份认证授权配置类型,配置相关参数。

    请您根据之前创建的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}

    预期结果:页面显示OAuth2 Proxy登录页面,包含Sign in with OpenID Connect按钮,则证明单点登录已经生效。

  2. 单击Sign in with OpenID Connect,在Keycloak的登录页面,请输入您在步骤一中创建的测试账号以及密码,单击登录

    预期结果:成功登录后,显示httpbin.org页面,包含HTTP MethodsAuthStatus codesRequest Inspection等接口分类。

  3. 单击Request inspection,选择/headers > try it out > Execute

    预期结果:执行后,在Server response的响应体中可以看到请求头信息,其中包含Authorization: Bearer {JWT}字段,表明请求已携带Keycloak颁发的JWT令牌。

  4. 请将上一步骤中Bearer之后请求携带的JWT在JWT Debugger中进行解析。更多关于JWT Debugger的内容,请参见JWT debugger

    预期结果:解析成功后,可以看到JWT的HEADER中算法为RS256,PAYLOAD中包含realm_access(角色信息)、preferred_username(用户名)、client_id(oauth2proxy)等Claims,表明JWT已通过ASM校验且附带了Keycloak中存储的用户信息。