配置使用远程 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 Deployment),且该工作负载具有政策可以匹配的标签。例如,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/v1beta1
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/v1beta1
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 示例。