Java应用中OAuth 2.0 On-Behalf-Of(OBO)流程:代表用户安全调用下游API
现代企业应用很少独立运行。用户可能通过 Web 或移动应用进行身份验证,调用基于 Java 的后端 API,而后端又可能需要调用额外的下游服务(如微服务或第三方 API)。在这些场景中,仅使用应用自身的身份往往不够。下游服务可能需要知道是谁发起了请求,并基于该用户的权限进行授权。这正是 OAuth 2.0 On-Behalf-Of (OBO) 流程的价值所在。本文将总结 OBO 流程的工作原理、在现代 Java 架构中的适用场景,以及如何在 Spring Boot 应用中安全地实现它。
每个下游服务如何知道原始用户是谁?
许多工程师首先想到的是:后端可以直接复用自身的应用凭据与其他服务通信。这在机器对机器通信中可行,但一旦需要基于用户进行授权,就力不从心了。考虑一个医疗应用场景:医生登录患者门户并请求病历。初始的 Java API 验证了请求,但获取病历可能需要调用另一个负责患者信息的内部 API。该下游 API 需要知道是哪个医生发起了请求,才能决定是否授予访问权限。如果 Java 后端只使用自身的应用身份,下游服务就会丢失用户上下文,无法基于医生的权限进行授权。这正是 OAuth 2.0 On-Behalf-Of (OBO) 流程要解决的问题。
什么是 OBO(On-Behalf-Of,代表用户)流程?
OBO 流程允许中间层服务(API A)为另一个下游服务(API B)获取访问令牌,同时保留已登录用户的身份和权限。API A 不是用自身的应用凭据调用 API B,而是将用户的访问令牌交换为针对 API B 的新令牌。流程如下:
结果,API B 收到代表实际用户的令牌,从而能够执行正确的授权检查。
为什么不使用客户端凭据(Client Credentials)?
许多开发者在调用下游 API 时错误地使用了客户端凭据流程。虽然客户端凭据适用于服务间通信,但它不携带用户上下文。以我们的医疗应用为例:
- 史密斯医生登录患者门户。
- Java API 从另一个服务获取患者记录。
- 下游服务必须验证史密斯医生的权限。
如果使用客户端凭据,下游服务只能看到应用身份,无法了解实际发起请求的用户。OBO 通过保留委托权限解决了这个问题。
典型企业用例
OBO 常用于:
- 医疗应用中访问患者记录
- 企业微服务
- 多层 API 架构
- 内部服务授权
- 审计与合规要求
许多实施零信任架构的组织都严重依赖 OBO 这样的委托授权模型。
在 Spring Boot 中实现 OBO
假设:
- Microsoft Entra ID(Azure AD)为身份提供者。
- API A 是一个 Spring Boot 应用。
- API B 是一个下游服务。
步骤 1:添加 MSAL4J 依赖
步骤 2:代表用户获取令牌
从前端应用接收传入的访问令牌。
至此,Java 应用已获取了一个新令牌,可用于调用 API B,同时保留用户身份。
步骤 3:调用下游 API
使用 Spring 的 RestTemplate:
现在 API B 收到一个代表已认证用户的委托令牌。
安全最佳实践
正确实现 OBO 至关重要。
1. 验证传入的令牌
始终验证:
- 签名
- 颁发者
- 受众
- 过期时间
切勿信任未经验证的客户端令牌。
2. 最小权限原则
仅请求下游 API 所需的作用域。
错误:https://graph.microsoft.com/.default
更好:
限制作用域可降低令牌泄露时的风险范围。
3. 切勿记录访问令牌
避免:logger.info(token);
访问令牌通常包含敏感声明和权限。
4. 保护客户端密钥
将密钥存储在:
- Azure Key Vault
- AWS Secrets Manager
- HashiCorp Vault
切勿将密钥存储在 application.properties 或源代码仓库中。
5. 实现令牌缓存
重复获取令牌会造成不必要的延迟。考虑缓存 OBO 令牌直至过期。大多数企业身份库已提供令牌缓存支持。
常见错误
我在指导新开发者时常遇到以下问题:
- 使用客户端凭据代替 OBO
- 将用户令牌直接传递给下游 API
- 请求过多作用域
- 记录 JWT 令牌
- 未验证令牌受众
- 硬编码客户端密钥
这些问题常导致授权失败或安全漏洞。
结论
随着组织采用微服务和 API 优先架构,跨服务边界保留用户身份变得越来越重要。OAuth 2.0 On-Behalf-Of 流程提供了一种安全且基于标准的方法,使 Java 应用能在调用下游 API 时保持原始用户的上下文和权限。通过正确实现 OBO,开发者可以构建更安全、可审计且符合现代零信任安全原则的应用。对于企业级 Java 团队而言,理解 OBO 已不再是可选项,而是构建安全分布式系统的基本要求。
DZone 贡献者的观点仅代表其个人立场。