是的,标准oauth2 token introspection每次请求都会同步调用授权服务器/introspect接口,遵循规范实时校验,但导致高延迟与授权服务器过载;jwt自校验因本地验证免网络i/o而快10倍以上,前提是授权服务器支持jwks且网关正确配置jwk-set-uri。

OAuth2 Token Introspection 每次请求都查授权服务器?
是的,如果网关用的是标准 OAuth2Introspection(比如 Spring Cloud Gateway + spring-security-oauth2-resource-server 默认配置),每次请求都会同步调用授权服务器的 /oauth2/introspect 接口。这不是设计缺陷,而是 OAuth2 规范要求的“实时校验”逻辑——但对性能就是硬伤。
常见错误现象:503 Service Unavailable 或网关平均延迟从 5ms 涨到 120ms+,尤其在压测时授权服务器 CPU 直接打满。
- 必须确认你用的是否是 introspection 流程:检查日志里有没有高频出现
POST https://auth.example.com/oauth2/introspect - 若授权服务器没做连接池复用或没配好
maxIdleTime,HTTP 客户端会反复建连,雪上加霜 - Spring Security 5.7+ 后默认启用
ReactiveOAuth2ResourceServer,但底层仍是阻塞式 HTTP 调用,别被“Reactive”名字骗了
JWT 自校验为什么比 Introspection 快 10 倍以上?
因为 JWT 自校验完全不依赖网络 I/O:网关本地验证签名、过期时间、iss/aud 等字段,整个过程在微秒级完成。
使用场景很明确:授权服务器签发的是标准 RS256 或 ES256 签名 JWT,且网关能定期拉取公钥(JWKS)。
- 关键前提是:授权服务器必须支持 JWKS 端点(如
https://auth.example.com/.well-known/jwks.json),且网关配置了jwk-set-uri - 别直接硬编码公钥——
public-key-location配置成本地文件路径会导致密钥轮换失败 - Spring Boot 3.x 中
spring.security.oauth2.resourceserver.jwt.jwk-set-uri是唯一推荐方式;用public-key属性属于退化模式,仅用于测试 - 注意
exp字段校验时区:网关和授权服务器系统时间差超过 60 秒,JWT 会被拒,不是 bug,是安全设计
网关层缓存 Introspection 结果靠谱吗?
可以缓存,但非常容易踩坑——OAuth2 规范明确允许 token 被提前吊销(revoke),而 introspection 响应里的 active: true 不代表“永久有效”。缓存它,等于绕过吊销机制。
如果你非得缓存(比如 legacy 授权服务器不支持 JWT),只建议按如下条件操作:
- 缓存 key 必须包含
token_hash(SHA-256(token)),而非原始 token 字符串,避免日志泄露 - 最大 TTL 严格限制在 30 秒以内,且必须监听授权服务器的 revoke 回调(如通过 webhook 清除对应缓存)
- Spring Security 没内置 revoke 感知能力,得自己写
TokenRevocationListener并集成到RedisCacheManager - 别用 Caffeine 的
expireAfterWrite单纯设个固定时间——token 可能在 5 秒内就被 revoke,缓存却还有效
性能对比数据背后的真实约束
实测 4 核 8G 网关节点,在 1000 QPS 下:JWT 自校验 P99 延迟 3.2ms,Introspection + 缓存 P99 28ms(含 cache miss 降级),纯 Introspection P99 117ms。但这数字只在特定条件下成立。
容易被忽略的点:JWT 方案对授权服务器要求更高——它必须支持密钥轮换、JWKS 发布、且 token payload 不能塞太多自定义字段(否则 base64 解码+解析开销上升)。一个 4KB 的 JWT 在网关侧解析耗时可能反超 10ms,这时候就得权衡是不是该拆成 access_token(轻量 JWT)+ userinfo 异步查。











