JooLun Plus 百科 ⬇ 源码下载

02.02 Feign 服务间调用

102353 于 2026-10-17 14:14:33 +08:00 修改了此页面

Feign 服务间调用

访问方式

项目当前存在三类访问方式:

  1. 外部经网关访问,且需要 token 鉴权。
    适用于后台绝大多数增删改查接口,用户登录后携带自己的 access token 即可访问。

  2. 外部经网关访问,但不需要 token 鉴权。
    适用于主动对外暴露的接口,配置 security.oauth2.client.release-urls 即可。

  3. 服务之间通过 Feign 访问。
    这类接口不对外直接暴露,只允许内部微服务调用。


最终规则

当前项目的内部 Feign 调用以“专用内部客户端”作为统一标准。

内部接口放行条件固定为:

  1. 请求中带有有效的 OAuth2 access token。
  2. 该 token 的授权方式为 client_credentials。
  3. 该 token 对应客户端在 inside-allowed-client-ids 白名单中。

当前实现下:

  1. from=Y 仅作为内部调用标记使用。
  2. 真正的鉴权依据是内部 bearer token。
  3. @Inside 接口只接受有效的内部 client_credentials token。

标准配置

当前推荐的统一配置如下:

security:
  oauth2:
    client:
      # 服务间调用专用客户端
      inside:
        client-id: internal-service
        client-secret: internal-service
        scope: server

      # 允许访问 @Inside 接口的客户端
      inside-allowed-client-ids:
        - internal-service

说明:

  1. 服务间 Feign 内部调用统一走 security.oauth2.client.inside.*。
  2. inside.* 只需要放在所有服务都会加载到的公共配置中,不需要每个服务单独配置。
  3. 各业务服务不再配置顶层 client-id、client-secret 和 scope。
  4. 内部调用客户端统一为 internal-service。
  5. 如果公共 inside.* 配置缺失,服务会在启动阶段直接报错,不再等到首次内部调用时才失败。

使用方式

例如 A 服务调用 B 服务内部接口。

1. 在 B 服务接口上标记 @Inside

@RestController
@AllArgsConstructor
@RequestMapping("/log")
public class SysLogController {
	private final SysLogService sysLogService;

	@Inside
	@PostMapping("/save")
	public R<Boolean> save(@Valid @RequestBody SysLog sysLog) {
		return R.ok(sysLogService.save(sysLog));
	}
}

2. 在 A 服务定义 Feign 接口

@FeignClient(contextId = "feignLogService", value = ServiceNameConstants.UMPS_ADMIN_SERVICE)
public interface FeignLogService {

	@PostMapping("/log/save")
	R<Boolean> saveLog(@RequestBody SysLog sysLog,
			@RequestHeader(SecurityConstants.FROM) String from);
}

3. 发起调用时传 SecurityConstants.FROM_IN

@Async
@Order
@EventListener(SysLogEvent.class)
public void saveSysLog(SysLogEvent event) {
	SysLog sysLog = event.getSysLog();
	feignLogService.saveLog(sysLog, SecurityConstants.FROM_IN);
}

当前调用行为固定为:

  1. 业务代码继续传 from=Y。
  2. 公共 Feign 拦截器识别 from=Y 后,自动申请并注入 internal-service 的 client_credentials token。
  3. 不带 from=Y 的普通链路,继续透传当前登录用户自己的 bearer token。

Gateway 规则

Gateway 仍然保留清理外部请求 from 请求头的逻辑:

  1. 外部请求经过 Gateway 时,伪造的 from=Y 会被去掉。
  2. 服务间 Feign 调用通常不经过 Gateway,因此内部调用标记会保留。
  3. 即使某个请求携带了 from=Y,如果没有有效内部 token,@Inside 也不会放行。

auth 特殊点

joolun-auth 既是认证中心,又负责内部 token 签发时的客户端信息查询。

因此当前实现包含本地数据源兜底,避免在认证中心内部出现“为了申请内部 token,又先通过 Feign 查客户端”的递归依赖。


最终验收口径

内部鉴权链路最终应满足:

  1. sys_oauth_client 中存在 internal-service,且授权方式包含 client_credentials。
  2. 所有服务都会加载到的公共配置中已存在 security.oauth2.client.inside.client-id=internal-service。
  3. 所有服务都会加载到的公共配置中已存在 inside-allowed-client-ids,且包含 internal-service。
  4. 服务间调用日志中,内部 token 申请客户端为 internal-service。
  5. @Inside 接口在没有有效内部 token 时返回拒绝,在有有效内部 token 时可正常访问。