前端登录JWT在微服务间传递的最佳实践咨询
微服务间传递JWT用户令牌的最佳实践分析
各方案优缺点拆解
方案1:直接传原始用户JWT
- 好处:实现起来最省事,不用额外做令牌交换,少了不少服务间的交互。
- 问题:风险太大。用户令牌一般有效期长,中间服务要是被攻破,攻击者拿着这个令牌就能冒充用户访问所有授权资源;而且用户令牌的受众(
aud字段)通常是面向公网的服务,下游服务可能直接拒绝请求;另外令牌里的用户敏感信息会被不必要的服务拿到,不符合最小权限原则。
方案2:用原始用户令牌换带用户声明的服务令牌
- 好处:既保证了服务间认证的安全,又能传递用户身份。服务令牌的受众是下游微服务,有效期可以设得很短(比如5分钟),就算泄露了,攻击者能用的时间也有限;同时只把下游服务需要的用户声明注入新令牌,不用传整个原始令牌,避免信息过度暴露。
- 问题:得多写点令牌交换的逻辑,不过Keycloak本身就支持这种兑换(比如用
urn:ietf:params:oauth:grant-type:jwt-bearer授权类型),不算太麻烦;需要注意只注入必要的用户声明,别搞冗余信息。
方案3:同时发服务令牌和原始用户令牌
- 好处:分工明确,服务间认服务令牌,用户身份认原始令牌,权限控制更灵活。
- 问题:请求头带俩令牌,占的空间大;原始用户令牌还是有泄露风险,下游服务还要处理两个令牌的验证,复杂度上去了。
方案4:把原始用户令牌嵌进服务令牌当声明
- 好处:只传一个令牌,请求头简单点;服务令牌管服务间认证,同时带着用户令牌,下游能拿到用户身份。
- 问题:服务令牌体积会变大,要是原始用户令牌长的话,可能影响请求速度;而且下游服务得先验证服务令牌,再单独验证里面嵌的原始用户令牌,多了一步验证工作。
最佳实践推荐
更推荐用方案2,理由很实在:
- 安全性拉满:服务令牌受众明确是下游微服务,短时效设计大大降低泄露风险,原始用户令牌根本不会在服务间流转,从根源减少了用户令牌泄露的可能。
- 权限控制合理:只给下游服务传它真正需要的用户声明,遵循最小权限原则,不会把用户敏感信息随便给出去。
- 符合标准玩法:Keycloak原生支持这种令牌兑换,直接用官方能力就行,不用自己瞎写复杂逻辑,后续维护也省心。
如果团队实在怕麻烦,而且所有下游服务都是内部完全可信的,也可以考虑方案1,但必须做这些优化:
- 把用户令牌的有效期改短,配上靠谱的刷新机制。
- 在Keycloak里配置好令牌受众,让下游服务只接受针对自己的令牌(要是原始令牌的
aud包含所有内部服务,就得调整配置)。 - 下游服务必须严格验证令牌的签名、有效期、受众这些字段,别放过非法请求。
另外补充个小技巧:服务间传令牌的时候,统一用Authorization: Bearer <token>这个标准请求头,所有服务都按这个规矩来;同时给每个微服务在Keycloak里配独立的客户端,开客户端认证,确保服务之间的调用都是可信的。
内容的提问来源于stack exchange,提问作者Shane Rowatt
相关产品推荐
相关产品推荐

