配置使用远程 JWKS 的 JWT 身份验证
借助 Cloud Service Mesh,您可以使用 Istio RequestAuthentication
自定义资源验证 JSON Web 令牌 (JWT),从而保护您的服务。此配置的关键部分是 jwksUri
字段,用于指定 JSON Web 密钥集 (JWKS) 提供方的 URI。此 JWKS 包含用于验证入站 JWT 的公钥。
重要提示:在 Cloud Service Mesh 中,数据平面(Envoy 代理)负责直接从 jwksUri
中提取 JWKS 密钥。Cloud Service Mesh 控制平面(由 Traffic Director 管理)不会进行外部调用来获取这些密钥。这意味着,与外部 JWKS 提供商的所有网络通信都源自工作负载的 Envoy 代理。
外部 JWKS 访问权限的前提条件
如需遵照本指南操作,您需要:
互联网访问组织政策:如果您的
jwksUri
指向外部互联网端点,则您的 Google Cloud 组织政策必须允许工作负载的出站互联网访问。具体而言,请验证组织政策constraints/compute.disableInternetNetworkEndpointGroup
是否未强制执行。如果此政策已启用,则从外部jwksUri
中提取 JWKS 将会失败。带有标签的 Kubernetes 工作负载:
RequestAuthentication
和AuthorizationPolicy
资源使用selector
来定位特定工作负载。您必须在集群中运行工作负载(例如 Kubernetes 部署),且该工作负载具有政策可以匹配的标签。例如,httpbin
示例已配置为使用app: httpbin
标签运行。您可以随意使用 Istio JWT 令牌指南中的httpbin
和curl
设置。
启用 JWKS 获取功能的方法
您可以通过以下两种主要方式配置 Cloud Service Mesh,以允许 Envoy 代理从外部 jwksUri
中提取 JWKS 密钥:
1. 使用 ServiceEntry
和 DestinationRule
进行手动配置(推荐)
这是大多数生产场景的推荐方法,对于使用 MCP 的 Cloud Service Mesh,此方法是必需的。此方法可让您明确控制网格与外部 JWKS 提供方的互动方式。
使用 ServiceEntry
定义外部服务
首先,您必须创建一个 Istio ServiceEntry
,使外部 JWKS 提供方成为网格中的已知服务。此资源可为数据平面中的 Envoy 代理实现 DNS 解析和适当的路由。
对于使用 jwksUri: "https://your-auth-provider.com/.well-known/jwks.json"
的 RequestAuthentication
政策,您将创建以下 ServiceEntry
:
apiVersion: networking.istio.io/v1
kind: ServiceEntry
metadata:
name: "external-jwks-provider-se"
namespace: your-namespace
spec:
hosts:
- "your-auth-provider.com" # Hostname from your jwksUri
location: MESH_EXTERNAL
ports:
- number: 443
name: https
protocol: TLS
resolution: DNS
使用 DestinationRule
配置连接设置
其次,您可能需要 DestinationRule
来指定与 JWKS 提供方的连接的客户端 TLS 设置,尤其是在提供方需要特定的 TLS 或 mTLS 配置时。
- 对于使用公开可信证书的提供方,请创建一个
DestinationRule
,并将tls.mode
设置为SIMPLE
,以启用标准服务器端 TLS 验证。 - 对于需要客户端证书 (mTLS) 的提供方,请将
tls.mode
设置为MUTUAL
,并提供 Envoy 必须提供的证书和密钥的路径。
此 DestinationRule
会为上一步中定义的 ServiceEntry
配置连接政策:
apiVersion: networking.istio.io/v1
kind: DestinationRule
metadata:
name: "external-jwks-provider-dr"
namespace: your-namespace
spec:
host: "your-auth-provider.com" # Must match a host in the ServiceEntry
trafficPolicy:
tls:
# Use SIMPLE for standard server-side TLS.
mode: SIMPLE
# If the JWKS provider uses a custom CA, provide the CA cert bundle.
# caCertificates: /path/to/provider-ca-cert.pem
# For providers requiring mTLS from Envoy, uncomment the following:
# mode: MUTUAL
# clientCertificate: /path/to/client-cert.pem
# privateKey: /path/to/client-key.pem
# caCertificates: /path/to/provider-ca-cert.pem
当这些资源存在且配置正确时,Envoy 会使用它们来建立安全连接并获取 JWKS 密钥。
2. Cloud Service Mesh(仅限 Traffic Director)的自动配置
如果 Cloud Service Mesh 在 RequestAuthentication
政策中找不到涵盖 HTTPS jwksUri
的主机名和端口的用户定义 ServiceEntry
,它会自动配置必要的设置,以便 Envoy 获取 JWKS 密钥。这种自动化功能可简化常见场景的设置,在这些场景中,默认连接到 jwksUri
(HTTPS,标准 TLS) 就足够了。
自动配置的条件:在以下情况下,系统会自动执行此行为:
- 您正在使用 Cloud Service Mesh 和 Traffic Director。
jwksUri
使用https
方案。jwksUri
指向外部的非集群本地服务。- 没有可见的
ServiceEntry
(考虑了RequestAuthentication
政策的命名空间和ServiceEntry
的exportTo
字段)已管理jwksUri
的主机名和端口。
如果满足这些条件,您的 Envoy 代理将配置为提取 JWKS,而无需您为该 jwksUri
创建明确的 ServiceEntry
或 DestinationRule
资源。
正在配置RequestAuthentication
无论使用哪种 JWKS 获取方法,您都可以使用 RequestAuthentication
政策定义 JWT 验证规则。
apiVersion: security.istio.io/v1
kind: RequestAuthentication
metadata:
name: "jwt-example"
namespace: your-namespace # Replace with your application's namespace
spec:
selector:
matchLabels:
app: your-app # Replace with your application's label (e.g. httpbin)
jwtRules:
- issuer: "testing@secure.istio.io"
jwksUri: "https://raw.githubusercontent.com/istio/istio/release-1.26/security/tools/jwt/samples/jwks.json"
jwtRules
中的关键字段(如需了解完整详情,请参阅 Istio RequestAuthentication 文档):
issuer
:JWT 的签发者。jwksUri
:提供方的公钥集 (JWKS) 的 HTTPS URI。fromHeaders
(可选):指定预期 JWT 所在的标头位置。fromParams
(可选):指定预期包含 JWT 的查询参数。forwardOriginalToken
(可选):如果为 true,则将原始令牌转发到上游服务。
使用 AuthorizationPolicy
强制执行 JWT 身份验证
如需拒绝缺少有效 JWT 的请求,您必须将 RequestAuthentication
政策与 AuthorizationPolicy
配对。以下政策仅允许向 your-app
工作负载发送请求,前提是这些请求提供来自指定签发者和正文的有效 JWT。
apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
name: "require-jwt-for-your-app"
namespace: your-namespace # Replace with your application's namespace
spec:
selector:
matchLabels:
app: your-app # Replace with your application's label (e.g. httpbin)
action: ALLOW
rules:
- from:
- source:
# This principal is typically in the format "issuer/subject"
requestPrincipals: ["testing@secure.istio.io/sub-from-jwt"] # Replace with the expected principal
如需查看有关在授权中使用 JWT 声明的更详细示例和使用场景,请参阅针对 JWT 令牌的 Istio 授权任务。
后续步骤
- 详细了解 Istio RequestAuthentication API。
- 查看 Cloud Service Mesh AuthorizationPolicy 概览。
- 探索 Istio 中针对 JWT 的 AuthorizationPolicy 示例。