ASM单点登录(一)ASM + Keycloak实现网格内应用单点登录

本文涉及的产品
容器服务 Serverless 版 ACK Serverless,952元额度 多规格
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
简介: 作为业内首个全托管Istio兼容的阿里云服务网格产品ASM,一开始从架构上就保持了与社区、业界趋势的一致性,控制平面的组件托管在阿里云侧,与数据面侧的用户集群独立。ASM产品是基于社区Istio定制实现的,在托管的控制面侧提供了用于支撑精细化的流量管理和安全管理的组件能力。通过托管模式,解耦了Istio组件与所管理的K8s集群的生命周期管理,使得架构更加灵活,提升了系统的可伸缩性。从2022年4月

作为业内首个全托管Istio兼容的阿里云服务网格产品ASM,一开始从架构上就保持了与社区、业界趋势的一致性,控制平面的组件托管在阿里云侧,与数据面侧的用户集群独立。ASM产品是基于社区Istio定制实现的,在托管的控制面侧提供了用于支撑精细化的流量管理和安全管理的组件能力。通过托管模式,解耦了Istio组件与所管理的K8s集群的生命周期管理,使得架构更加灵活,提升了系统的可伸缩性。从2022年4月1日起,阿里云服务网格ASM正式推出商业化版本, 提供了更丰富的能力、更大的规模支持及更完善的技术保障,更好地满足客户的不同需求场景, 详情可见产品介绍:https://www.aliyun.com/product/servicemesh

背景

单点登录(Single Sign On),简称为 SSO,是目前比较流行的企业业务整合的解决方案之一。SSO的定义是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。通常在将应用接入到账号管理系统时,需要应用额外维护与认证/授权系统的认证/授权流程,而借助服务网格的外部授权能力,可以通过配置轻松地接入支持OIDC协议的认证/授权系统实现单点登录。本文选用广泛应用的开源项目keycloak作为认证授权系统进行演示,将服务网格内应用接入到Keycloak进行单点登录。

准备工作

  • 创建一个ASM实例及ACK集群,并且将ACK集群加入至ASM
  • 创建一个ASM网关,用于随后将服务暴露至公网
  • 为default命名空间启用Sidecar自动注入

部署和配置

一、部署演示应用和keycloak

使用下面的yaml,将httpbin应用部署至ACK集群

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

使用下面的yaml,将keycloak部署至ACK集群

apiVersion: v1
kind: Service
metadata:
  name: keycloak
  labels:
    app: keycloak
spec:
  ports:
  - name: http
    port: 8080
    targetPort: 8080
  selector:
    app: keycloak
  type: LoadBalancer
---
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控制台。请参考https://help.aliyun.com/document_detail/164895.html?spm=5176.13895322.help.dexternal.23f55fcfolpSUG为https服务创建证书,并命名为:myexample-credential。证书就绪后,使用下面的yaml在ASM集群创建网关规则和虚拟服务,将keycloak暴露于公网

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
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  creationTimestamp: '2022-06-09T11:44:20Z'
  generation: 18
  name: ingressgateway-vs
  namespace: istio-system
  resourceVersion: '7643220'
  uid: bcff89f3-6842-4049-945b-76cb9f9d9961
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

配置完成后,通过http://${入口网关地址}即可访问keycloak应用

三、配置keycloak

使用管理员账号登录KeyCloak控制台,选择您希望使用的Realm。点击导航栏中的Configure,再点击展开的子菜单中的Clients

点击右侧Create,创建用于oauth2proxy的client配置,按照下列值填写,并点击Save保存

  • Client ID: oauth2proxy
  • Client Protocol: openid-connect

创建完成后,回到Client列表,点击刚才创建的client,进入配置页面

在配置页面Settings选项卡中,找到AccessType,下拉选择Confidential:

然后点击上方Mappers选项卡,点击Create,创建如下2个mapper

最后,我们为keycloak添加一个测试账号用于演示登录认证流程,导航栏Manage -> Users -> Add user,为了简化演示流程,我们直接将Email Verified设置为On,表明该用户已经验证过邮件了。

至此,Keycloak的配置已经基本完毕。

四、部署oauth2proxy

本文提供了部署oauth2proxy的yaml模板,您需要先获得如下值,并替换至模板内,再进行部署

  • 入口网关地址:ASM控制台 -> 网格实例 -> ASM网关 -> Kubernetes服务列可得到入口网关IP地址
  • ClientID: 第三步创建的ClientID
  • ClientSecret:keycloak控制台 -> Configure -> Clients -> 在列表中点击第三步创建的Client -> Credentials选项卡 -> Secret
  • CookieSecret: 参考:
apiVersion: apps/v1
kind: Deployment
metadata:
  name: oauth2-proxy
  namespace: istio-system
spec:
  selector:
    matchLabels:
      app: oauth2-proxy
  template:
    metadata:
      labels:
        app: oauth2-proxy
    spec:
      containers:
      - name: oauth2-proxy
        image: quay.io/oauth2-proxy/oauth2-proxy:v7.2.0
        args:
        - --provider=keycloak-oidc
        - --cookie-secure=true # 本例中需要使用https访问应用,所以设置为true
        - --redirect-url=https://${入口网关地址}/oauth2/callback
        - --cookie-samesite=lax
        - --cookie-refresh=1h
        - --cookie-expire=4h
        - --cookie-name=_oauth2_proxy_istio_ingressgateway
        - --set-authorization-header=true
        - --email-domain=*
        - --http-address=0.0.0.0:4180
        - --upstream=static://200
        - --skip-provider-button=false
        - --whitelist-domain=*
        - --oidc-issuer-url=http://${入口网关地址}/realms/master
        - --skip-provider-button=false
        - --scope=openid profile email
        env:
        - name: OAUTH2_PROXY_CLIENT_ID
          value: "${ClientID}"
        - name: OAUTH2_PROXY_CLIENT_SECRET
          value: "${ClientSecret}"
        - name: OAUTH2_PROXY_COOKIE_SECRET
          value: "${CookieSecret}"
        resources:
          requests:
            cpu: 10m
            memory: 100Mi
        ports:
        - containerPort: 4180
          protocol: TCP
        readinessProbe:
          periodSeconds: 3
          httpGet:
            path: /ping
            port: 4180

五、创建外部授权服务及授权策略

打开ASM控制台,进入网格实例,点击导航栏中“零信任安全”,展开菜单后点击“外部授权服务”,点击“创建”

协议选择HTTP、服务地址为第三步部署的oauth2proxy的集群内域名,即:oauth2-proxy.istio-system.svc.cluster.local,服务端口即为oauth2-proxy服务的4180端口,超时时间设置为10秒。为了使得授权流程及认证成功后的身份信息能够被正确传递,还需设置以下几项:

  • 启用“在鉴权请求中携带header”,并添加下列值
  • cookie
  • x-forward-access-token
  • 启用“鉴权通过时覆盖header”,并添加下列值
  • authorization
  • cookie
  • path
  • x-auth-request-access-token
  • x-forwarded-access-token
  • 启用“鉴权失败时覆盖header”,并添加下列值
  • content-type
  • set-cookie
  • 启用“在鉴权请求中携带请求body”,并设置最大长度为10240(10K)。

点击确定创建外部授权服务。

接下来还需要创建授权策略,将请求指向外部授权服务进行授权流程。在当前服务网格实例左侧导航栏点击“授权策略”,点击使用yaml创建,将下面yaml拷贝粘贴,点击确定创建。

apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: oidc
  namespace: istio-system
spec:
  action: CUSTOM
  provider:
    name: httpextauth-oidc
  rules:
    - {}
  selector:
    matchLabels:
      istio: ingressgateway

验证

经过前面5个步骤的配置,我们现在可以访问应用以验证单点登录是否已经生效。在浏览器输入https://入口网关地址,访问应用,返回的页面为oauth2-proxy的登录页面。

点击“Sign in with Keycloak OIDC”,将跳转到keycloak登录页面,

输入账号密码,点击登录,成功跳转到应用页面:

点击Httpbin应用页面上的Request inspection,展开后点击/headers,点击右侧Try-it-out,再点击Execute,即可查看请求的Headers,可以看到,请求中携带了Authorization和Cookie两个Header,Authorization为一个JwtToken,可通过工具进行Decode,查看JwtToken中携带的身份信息。

目录
相关文章
|
9天前
|
Kubernetes Cloud Native JavaScript
为使用WebSocket构建的双向通信应用带来基于服务网格的全链路灰度
介绍如何使用为基于WebSocket的云原生应用构建全链路灰度方案。
|
4月前
|
Kubernetes Dubbo Cloud Native
如何将Dubbo应用接入服务网格
介绍使用传统Dubbo微服务体系的客户要如何将自己的服务接入到服务网格这一新一代云原生基础设施。
|
4月前
|
Cloud Native 测试技术 开发者
阿里云服务网格ASM多集群实践(二):高效按需的应用多环境部署与全链路灰度发布
介绍服务网格ASM提出的一种多集群部署下的多环境部署与全链路灰度发布解决方案。
|
6月前
|
负载均衡 监控 Go
Golang深入浅出之-Go语言中的服务网格(Service Mesh)原理与应用
【5月更文挑战第5天】服务网格是处理服务间通信的基础设施层,常由数据平面(代理,如Envoy)和控制平面(管理配置)组成。本文讨论了服务发现、负载均衡和追踪等常见问题及其解决方案,并展示了使用Go语言实现Envoy sidecar配置的例子,强调Go语言在构建服务网格中的优势。服务网格能提升微服务的管理和可观测性,正确应对问题能构建更健壮的分布式系统。
446 1
|
11月前
|
人工智能 Kubernetes TensorFlow
轻松搭建基于服务网格的 AI 应用,然后开始玩
轻松搭建基于服务网格的 AI 应用,然后开始玩
65282 28
|
监控 安全 大数据
阿里服务的ASM、MSE和ARMS都有其各自的应用场景
阿里服务的ASM、MSE和ARMS都有其各自的应用场景
397 39
|
监控 安全 测试技术
服务网格和CI/CD集成:讨论服务网格在持续集成和持续交付中的应用。
服务网格和CI/CD集成:讨论服务网格在持续集成和持续交付中的应用。
128 0
|
监控 安全 Cloud Native
构建无缝的服务网格体验:分享在生产环境中构建和管理服务网格的最佳实践
构建无缝的服务网格体验:分享在生产环境中构建和管理服务网格的最佳实践
61 0
|
存储 Serverless 异构计算
使用ASM管理Knative服务(2):使用Knative on ASM部署Serverless应用
如何在阿里云服务网格ASM中开启Knative on ASM功能, 并结合ACK或者ASK部署管理Serverless应用服务。
638 0
使用ASM管理Knative服务(2):使用Knative on ASM部署Serverless应用
|
Prometheus 监控 Kubernetes
使用ASM网格拓扑观测多集群的流量控制与容灾场景
作为业内首个全托管Istio兼容的阿里云服务网格产品ASM,一开始从架构上就保持了与社区、业界趋势的一致性,控制平面的组件托管在阿里云侧,与数据面侧的用户集群独立。ASM产品是基于社区Istio定制实现的,在托管的控制面侧提供了用于支撑精细化的流量管理和安全管理的组件能力。通过托管模式,解耦了Istio组件与所管理的K8s集群的生命周期管理,使得架构更加灵活,提升了系统的可伸缩性。从2022年4月