Feign 服务间调用
访问方式
项目当前存在三类访问方式:
-
外部经网关访问,且需要
token鉴权。
适用于后台绝大多数增删改查接口,用户登录后携带自己的 access token 即可访问。 -
外部经网关访问,但不需要
token鉴权。
适用于主动对外暴露的接口,配置security.oauth2.client.release-urls即可。 -
服务之间通过 Feign 访问。
这类接口不对外直接暴露,只允许内部微服务调用。
最终规则
当前项目的内部 Feign 调用以“专用内部客户端”作为统一标准。
内部接口放行条件固定为:
- 请求中带有有效的 OAuth2 access token。
- 该 token 的授权方式为
client_credentials。 - 该 token 对应客户端在
inside-allowed-client-ids白名单中。
当前实现下:
from=Y仅作为内部调用标记使用。- 真正的鉴权依据是内部 bearer token。
@Inside接口只接受有效的内部client_credentialstoken。
标准配置
当前推荐的统一配置如下:
security:
oauth2:
client:
# 服务间调用专用客户端
inside:
client-id: internal-service
client-secret: internal-service
scope: server
# 允许访问 @Inside 接口的客户端
inside-allowed-client-ids:
- internal-service
说明:
- 服务间 Feign 内部调用统一走
security.oauth2.client.inside.*。 inside.*只需要放在所有服务都会加载到的公共配置中,不需要每个服务单独配置。- 各业务服务不再配置顶层
client-id、client-secret和scope。 - 内部调用客户端统一为
internal-service。 - 如果公共
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);
}
当前调用行为固定为:
- 业务代码继续传
from=Y。 - 公共 Feign 拦截器识别
from=Y后,自动申请并注入internal-service的client_credentialstoken。 - 不带
from=Y的普通链路,继续透传当前登录用户自己的 bearer token。
Gateway 规则
Gateway 仍然保留清理外部请求 from 请求头的逻辑:
- 外部请求经过 Gateway 时,伪造的
from=Y会被去掉。 - 服务间 Feign 调用通常不经过 Gateway,因此内部调用标记会保留。
- 即使某个请求携带了
from=Y,如果没有有效内部 token,@Inside也不会放行。
auth 特殊点
joolun-auth 既是认证中心,又负责内部 token 签发时的客户端信息查询。
因此当前实现包含本地数据源兜底,避免在认证中心内部出现“为了申请内部 token,又先通过 Feign 查客户端”的递归依赖。
最终验收口径
内部鉴权链路最终应满足:
sys_oauth_client中存在internal-service,且授权方式包含client_credentials。- 所有服务都会加载到的公共配置中已存在
security.oauth2.client.inside.client-id=internal-service。 - 所有服务都会加载到的公共配置中已存在
inside-allowed-client-ids,且包含internal-service。 - 服务间调用日志中,内部 token 申请客户端为
internal-service。 @Inside接口在没有有效内部 token 时返回拒绝,在有有效内部 token 时可正常访问。