作为业内首个全托管Istio兼容的阿里云服务网格产品ASM,一开始从架构上就保持了与社区、业界趋势的一致性,控制平面的组件托管在阿里云侧,与数据面侧的用户集群独立。ASM产品是基于社区Istio定制实现的,在托管的控制面侧提供了用于支撑精细化的流量管理和安全管理的组件能力。通过托管模式,解耦了Istio组件与所管理的K8s集群的生命周期管理,使得架构更加灵活,提升了系统的可伸缩性。从2022年4月1日起,阿里云服务网格ASM正式推出商业化版本, 提供了更丰富的能力、更大的规模支持及更完善的技术保障,更好地满足客户的不同需求场景, 详情可见产品介绍:https://www.aliyun.com/product/servicemesh。
背景
在上一篇中我们通过ASM外部授权 + Keycloak的方式实现了网格内应用单点登录。若不想自行运维keycloak或类似认证/授权系统,同样可以使用阿里云IDaaS作为认证/授权管理系统来实现单点登录,在本文中,我们通过对创建IDaaS实例并进行简单的配置,实现网格内应用单点登录。
准备工作
-
创建一个ASM实例及ACK集群,并且将ACK集群加入至ASM
-
创建一个ASM网关,用于随后将服务暴露至公网
-
为default命名空间启用Sidecar自动注入
部署和配置
一、创建EIAM 云身份服务实例及测试账号
打开云身份服务控制台,创建IDaaS实例,参见文档:https://help.aliyun.com/document_detail/408892.html?spm=5176.b73997031.help.dexternal.5f1075080MP3wA
一个IDaaS实例可以看做是一个账号系统,这一步即可理解为创建了一个账号系统。接下来在账号系统中创建一个测试账号。
点击IDaaS实例名称进入IDaaS实例
点击导航栏“账户”,并在“账户”页面点击“创建账户”按钮
输入账户信息,点击保存
至此,我们已经在阿里云IDaaS上创建了一个单点登录账户系统,且添加了一个账户。
二、添加和配置OIDC应用
IDaaS实例中的应用可以理解为接口,该IDaaS实例可以通过不同的应用暴露接口,以各种方式进行单点登录,本文中将使用OIDC应用进行演示。
进入上一步创建的IDaaS实例,点击左侧导航栏中“应用”,选择“标准协议”,再点击OIDC应用的“添加应用”按钮,创建一个新的OIDC应用。
点击导航栏“应用”,回到应用列表
点击应用名称进入刚才创建的OIDC应用,点击“登录访问”选项卡,再点击“单点登录”子选项卡。
设置redirect URI为http://ASM网关SLB地址/oauth2/callback。
下拉页面,点击显示高级配置。
确认email和profile scope被勾选
点击保存,将上述变更保存。
然后点击授权选项卡,为第一步创建的账户授权允许通过OIDC登录这个账户。
选择步骤一创建的账户,并点击“保存授权”。
三、部署oauth2proxy
本例中,我们需要将oauth2proxy作为外部鉴权服务,未携带认证信息的请求被发往鉴权服务时,会触发登录流程,登录成功后,鉴权服务则会放行请求,请求携带身份信息被发往应用。
本文提供了oauth2proxy部署的模板,需要将模板中的待填写配置项(由${}包裹)进行替换后,部署至ACK集群。配置中的部分字段需要从IdP处获取或自行生成。
-
Issuer:阿里云身份认证服务控制台 - 应用 - 步骤2中创建的OIDC应用 - 登录访问 - 单点登录 - 应用配置信息 - Issuer
-
ClientID: 阿里云身份认证服务控制台 - 应用 - 步骤2中创建的OIDC应用 - 通用配置 - client_id
-
ClientSecret: 阿里云身份认证服务控制台 - 应用 - 步骤2中创建的OIDC应用 - 通用配置 - client_secret
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=oidc
- --cookie-secure=false
- --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=${Issuer}
- --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
---
apiVersion: v1
kind: Service
metadata:
name: oauth2-proxy
namespace: istio-system
spec:
type: NodePort
ports:
- name: http
port: 4180
protocol: TCP
targetPort: 4180
nodePort: 30020
selector:
app: oauth2-proxy
四、部署测试应用并将其暴露于网关
本文使用httpbin应用作为测试,该应用可以辅助查看请求内容,便于验证登录后的身份信息。您可以使用如下YAML在ACK集群 default 命名空间下部署httpbin应用。
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
将应用部署至ACK集群后,配置ASM网关规则及虚拟服务,将应用通过网关暴露出来。先应用下方网关规则到ASM实例。
apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
name: ingressgateway
namespace: istio-system
spec:
selector:
app: istio-ingressgateway
servers:
- hosts:
- '*'
port:
name: http
number: 80
protocol: HTTP
再应用下方虚拟服务到ASM实例,虚拟服务仅指定了一条指向httpbin应用的默认路由规则。
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: ingressgateway-vs
namespace: istio-system
spec:
gateways:
- ingressgateway
hosts:
- '*'
http:
- name: default
route:
- destination:
host: httpbin.default.svc.cluster.local
port:
number: 8000
五、创建外部授权服务及授权策略
打开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个步骤的配置,我们现在可以访问应用以验证单点登录是否已经生效。在浏览器输入入口网关地址,访问应用,返回的页面为oauth2-proxy的登录页面。
点击“Sign in with OpenID Connect”,将跳转到阿里云IDaaS登录页面
输入第一步创建的测试账号和密码,点击登录,登录成功后,页面跳转至httpbin应用。
点击Httpbin应用页面上的Request inspection,展开后点击/headers,点击右侧Try-it-out,再点击Execute,即可查看请求的Headers,可以看到,请求中携带了Authorization和Cookie两个Header,Authorization为一个JwtToken,可通过工具进行Decode,查看JwtToken中携带的身份信息。