入口网关后面的单个服务的 istio JWT 身份验证
istio JWT authentication for single service behind ingress gateway
我在 AKS (v1.16.13) 上有 2 个服务 运行 并部署了以下 istio (v1.7.3) 配置。第一个是 UI,我在其中调用 OIDC 流程并获取 JWT 令牌,第二个是后端服务,它应该需要有效的 JWT 令牌。
apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
name: myapp-gateway
namespace: "istio-system"
spec:
selector:
istio: ingressgateway
servers:
- hosts:
- myapp.com
port:
name: http-myapp
number: 80
protocol: HTTP
tls:
httpsRedirect: true
- hosts:
- myapp.com
port:
name: https-myapp
number: 443
protocol: HTTPS
tls:
credentialName: myapp-credential
mode: SIMPLE
---
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: myapp
namespace: myapp
spec:
gateways:
- istio-system/myapp-gateway
hosts:
- myapp.com
http:
- match:
- uri:
prefix: /ui
route:
- destination:
host: myapp-ui.myapp.svc.cluster.local
port:
number: 4200
- match:
- uri:
prefix: /backend/
rewrite:
uri: /
route:
- destination:
host: myapp-service-backend.myapp.svc.cluster.local
port:
number: 8080
---
apiVersion: security.istio.io/v1beta1
kind: RequestAuthentication
metadata:
name: myapp-jwt-backend
namespace: myapp
spec:
jwtRules:
- issuer: https://oktapreview.com
selector:
matchLabels:
app: myapp-service-backend
使用该配置,如果我调用 myapp.com/backend,我希望得到 401,但事实并非如此。请求身份验证未启动。
经过进一步研究 (https://discuss.istio.io/t/cannot-use-jwt-policy-with-an-externalname-virtualservice-target/2794/3),我发现我无法在 VirtualService 上应用 RequestAuthentication,而只能在 Gateway 上应用,这对我来说很奇怪但没问题。我已将 RequestAuthentication 更改为以下内容,但在调用后端后仍然没有任何变化:
apiVersion: security.istio.io/v1beta1
kind: RequestAuthentication
metadata:
name: myapp-jwt-backend
namespace: istio-system
spec:
jwtRules:
- issuer: https://oktapreview.com
selector:
matchLabels:
istio: myapp-gateway
您知道如何为我的用例设置 istio 吗?假设 RequestAuthentication 可以在网关上运行,我需要 2 个网关吗? 1 个用于 UI,第二个用于后端?好像有点矫枉过正了。
感谢 sachin 的评论并再次浏览文档让我意识到我需要在 RequestAuthentication 之上使用 AuthorizationPolicy:
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: myapp-require-jwt-backend
spec:
action: ALLOW
rules:
- from:
- source:
requestPrincipals:
- https://xxx/*
selector:
matchLabels:
app: myapp-service-backend
请求身份验证只是确保在提供 JWT 令牌时,它必须是有效的。如果没有token,就直接通过请求。
我在 AKS (v1.16.13) 上有 2 个服务 运行 并部署了以下 istio (v1.7.3) 配置。第一个是 UI,我在其中调用 OIDC 流程并获取 JWT 令牌,第二个是后端服务,它应该需要有效的 JWT 令牌。
apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
name: myapp-gateway
namespace: "istio-system"
spec:
selector:
istio: ingressgateway
servers:
- hosts:
- myapp.com
port:
name: http-myapp
number: 80
protocol: HTTP
tls:
httpsRedirect: true
- hosts:
- myapp.com
port:
name: https-myapp
number: 443
protocol: HTTPS
tls:
credentialName: myapp-credential
mode: SIMPLE
---
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: myapp
namespace: myapp
spec:
gateways:
- istio-system/myapp-gateway
hosts:
- myapp.com
http:
- match:
- uri:
prefix: /ui
route:
- destination:
host: myapp-ui.myapp.svc.cluster.local
port:
number: 4200
- match:
- uri:
prefix: /backend/
rewrite:
uri: /
route:
- destination:
host: myapp-service-backend.myapp.svc.cluster.local
port:
number: 8080
---
apiVersion: security.istio.io/v1beta1
kind: RequestAuthentication
metadata:
name: myapp-jwt-backend
namespace: myapp
spec:
jwtRules:
- issuer: https://oktapreview.com
selector:
matchLabels:
app: myapp-service-backend
使用该配置,如果我调用 myapp.com/backend,我希望得到 401,但事实并非如此。请求身份验证未启动。
经过进一步研究 (https://discuss.istio.io/t/cannot-use-jwt-policy-with-an-externalname-virtualservice-target/2794/3),我发现我无法在 VirtualService 上应用 RequestAuthentication,而只能在 Gateway 上应用,这对我来说很奇怪但没问题。我已将 RequestAuthentication 更改为以下内容,但在调用后端后仍然没有任何变化:
apiVersion: security.istio.io/v1beta1
kind: RequestAuthentication
metadata:
name: myapp-jwt-backend
namespace: istio-system
spec:
jwtRules:
- issuer: https://oktapreview.com
selector:
matchLabels:
istio: myapp-gateway
您知道如何为我的用例设置 istio 吗?假设 RequestAuthentication 可以在网关上运行,我需要 2 个网关吗? 1 个用于 UI,第二个用于后端?好像有点矫枉过正了。
感谢 sachin 的评论并再次浏览文档让我意识到我需要在 RequestAuthentication 之上使用 AuthorizationPolicy:
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: myapp-require-jwt-backend
spec:
action: ALLOW
rules:
- from:
- source:
requestPrincipals:
- https://xxx/*
selector:
matchLabels:
app: myapp-service-backend
请求身份验证只是确保在提供 JWT 令牌时,它必须是有效的。如果没有token,就直接通过请求。