自定義授權服務
更新時間 2025-10-15 11:48:37
最近更新時間: 2025-10-15 11:48:37
分享文章
本章節介紹自定義授權服務
前提條件
- 已開通云容器引擎,至少有一個云容器引擎集群實例。產品入口:云容器引擎。
- 開通天翼云服務網格實例。
操作步驟
創建測試命名空間
kubectl create ns foo
打開sidecar自動注入
kubectl label ns foo istio-injection=enabled
部署sleep和httpbin應用
apiVersion: v1
kind: ServiceAccount
metadata:
name: sleep
---
apiVersion: v1
kind: Service
metadata:
name: sleep
labels:
app: sleep
service: sleep
spec:
ports:
- port: 80
name: http
selector:
app: sleep
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: sleep
spec:
replicas: 1
selector:
matchLabels:
app: sleep
template:
metadata:
labels:
app: sleep
spec:
terminationGracePeriodSeconds: 0
serviceAccountName: sleep
containers:
- name: sleep
image: registry-vpc-crs-huadong1.cnsp-internal.daliqc.cn/library/curl
command: ["/bin/sleep", "infinity"]
imagePullPolicy: IfNotPresent
volumeMounts:
- mountPath: /etc/sleep/tls
name: secret-volume
volumes:
- name: secret-volume
secret:
secretName: sleep-secret
optional: true
---
部署外部授權服務
apiVersion: v1
kind: Service
metadata:
name: ext-authz
labels:
app: ext-authz
spec:
ports:
- name: http
port: 8000
targetPort: 8000
- name: grpc
port: 9000
targetPort: 9000
selector:
app: ext-authz
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: ext-authz
spec:
replicas: 1
selector:
matchLabels:
app: ext-authz
template:
metadata:
labels:
app: ext-authz
spec:
containers:
- image: registry-vpc-crs-huadong1.cnsp-internal.daliqc.cn/library/ext-authz:1.16.2
imagePullPolicy: IfNotPresent
name: ext-authz
ports:
- containerPort: 8000
- containerPort: 9000
---
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: registry-vpc-crs-huadong1.cnsp-internal.daliqc.cn/library/httpbin
imagePullPolicy: IfNotPresent
name: httpbin
ports:
- containerPort: 80
部署完成后,在foo命名空間下看到3個服務

不使用授權策略的情況下,驗證從sleep應用訪問httpbin應用沒有被攔截(返回狀態碼200):
kubectl exec "$(kubectl get pod -l
app=sleep -n foo -o jsonpath={.items..metadata.name})" -c sleep -n foo --
curl //httpbin.foo:8000/ip -s -o /dev/null -w "%{http_code}\n"
200
查看外部授權服務已經啟動,HTTP和gRPC授權服務分別監聽8000和9000端口:
kubectl logs "$(kubectl get pod -l
app=ext-authz -n foo -o jsonpath={.items..metadata.name})" -n foo -c
ext-authz
2023/08/14 11:26:54 Starting HTTP server at
[::]:8000
2023/08/14 11:26:54 Starting gRPC server at
[::]:9000
添加外部授權服務
將上面的HTTP和gRPC服務添加到服務網格的外部授權服務內。
定義授權策略&驗證訪問
定義如下授權策略,對httpbin應用的/headers路徑的請求將被轉發到第三方授權服務進行驗證:
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: ext-authz
spec:
selector:
matchLabels:
app: httpbin
action: CUSTOM
provider:
# The provider name must match the extension provider defined in the mesh config.
# You can also replace this with sample-ext-authz-http to test the other external authorizer definition.
name: sample-ext-authz-grpc
rules:
# The rules specify when to trigger the external authorizer.
- to:
- operation:
paths: ["/headers"]
從sleep應用請求httpbin的/headers路徑,由于請求頭帶了"x-ext-authz:deny",請求被攔截:
kubectl exec "$(kubectl get pod -l app=sleep -n foo -o jsonpath={.items..metadata.name})" -c sleep -n foo -- curl "//httpbin.foo:8000/headers" -H "x-ext-authz: deny" -s
denied by ext_authz for not found header `x-ext-authz: allow` in the request
修改請求,帶上"x-ext-authz: allow"頭部,請求放行:
kubectl exec "$(kubectl get pod -l app=sleep -n foo -o jsonpath={.items..metadata.name})" -c sleep -n foo -- curl "//httpbin.foo:8000/headers" -H "x-ext-authz: allow" -s
{
"headers": {
"Accept": "*/*",
"Host": "httpbin.foo:8000",
"User-Agent": "curl/8.2.1",
"X-B3-Parentspanid": "eb42a8165099e7db",
"X-B3-Sampled": "1",
"X-B3-Spanid": "cd6540ba1cfd9e8c",
"X-B3-Traceid": "e7e15cc10dc66630eb42a8165099e7db",
"X-Envoy-Attempt-Count": "1",
"X-Ext-Authz": "allow",
"X-Ext-Authz-Additional-Header-Override": "grpc-additional-header-override-value",
"X-Ext-Authz-Check-Received": "source:{address:{socket_address:{address:\"10.1.0.25\" port_value:37654}} principal:\"spiffe://cluster.local/ns/foo/sa/sleep\"} destination:{address:{socket_address:{address:\"10.1.0.24\" port_value:80}} principal:\"spiffe://cluster.local/ns/foo/sa/httpbin\"} request:{time:{seconds:1692015383 nanos:990298000} http:{id:\"7462237371770661564\" method:\"GET\" headers:{key:\":authority\" value:\"httpbin.foo:8000\"} headers:{key:\":method\" value:\"GET\"} headers:{key:\":path\" value:\"/headers\"} headers:{key:\":scheme\" value:\"http\"} headers:{key:\"accept\" value:\"*/*\"} headers:{key:\"user-agent\" value:\"curl/8.2.1\"} headers:{key:\"x-b3-sampled\" value:\"1\"} headers:{key:\"x-b3-spanid\" value:\"eb42a8165099e7db\"} headers:{key:\"x-b3-traceid\" value:\"e7e15cc10dc66630eb42a8165099e7db\"} headers:{key:\"x-envoy-attempt-count\" value:\"1\"} headers:{key:\"x-ext-authz\" value:\"allow\"} headers:{key:\"x-forwarded-client-cert\" value:\"By=spiffe://cluster.local/ns/foo/sa/httpbin;Hash=c32db24acfa670a8bbe46f0897ebb70b9ccc0e630ee32afcd1ec037d6616e6c5;Subject=\\\"\\\";URI=spiffe://cluster.local/ns/foo/sa/sleep\"} headers:{key:\"x-forwarded-proto\" value:\"http\"} headers:{key:\"x-request-id\" value:\"aba7b68c-6bee-9d58-b163-7454075c6ece\"} path:\"/headers\" host:\"httpbin.foo:8000\" scheme:\"http\" protocol:\"HTTP/1.1\"}} metadata_context:{}",
"X-Ext-Authz-Check-Result": "allowed",
"X-Forwarded-Client-Cert": "By=spiffe://cluster.local/ns/foo/sa/httpbin;Hash=c32db24acfa670a8bbe46f0897ebb70b9ccc0e630ee32afcd1ec037d6616e6c5;Subject=\"\";URI=spiffe://cluster.local/ns/foo/sa/sleep"
}
}