You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

通过FeignClient路由至Spring Cloud API Gateway实现JWT授权问题

问题分析

你的Feign调用之所以未生效,核心原因是Feign默认不会自动传递当前请求的Authorization头(即JWT Token),导致网关的AuthorizationHeaderFilter拿不到Token,验证不通过,请求被拦截。

解决方案

下面提供两种可行的实现方式,让Feign调用携带JWT Token经过网关验证:

方式一:手动传递Authorization头

直接在Feign接口方法中添加@RequestHeader参数,调用时从当前请求中获取Token传入:

1. 修改Feign接口

@FeignClient(name = "RATING-SERVICE", url="http://localhost:9000")
public interface RatingService {

    @GetMapping("/ratingsdata/{managerInput}/{peerInput}/{dept}")
    Double getRating(
        @RequestHeader("Authorization") String authorizationHeader,
        @PathVariable Double managerInput, 
        @PathVariable Double peerInput,
        @PathVariable String dept);
}

2. 在调用处传入Token

@Autowired
private RatingService ratingService;
@Autowired
private HttpServletRequest request;

// 从当前请求中获取Authorization头,传入Feign调用
Double empRating = ratingService.getRating(
    request.getHeader("Authorization"),
    employee.getManagerPoints(), 
    employee.getPeersPoints(), 
    employee.getDepartment().getDeptName());

方式二:全局自动传递Token(推荐)

实现Feign的RequestInterceptor,自动从当前请求上下文提取Authorization头并添加到Feign请求中,无需手动传递:

1. 创建Feign请求拦截器

import feign.RequestInterceptor;
import feign.RequestTemplate;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;

@Component
public class FeignAuthInterceptor implements RequestInterceptor {

    @Override
    public void apply(RequestTemplate template) {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (attributes != null) {
            HttpServletRequest request = attributes.getRequest();
            String authorization = request.getHeader("Authorization");
            if (authorization != null) {
                template.header("Authorization", authorization);
            }
        }
    }
}

2. 简化Feign接口

拦截器生效后,Feign接口无需额外参数,保持原有写法即可:

@FeignClient(name = "RATING-SERVICE", url="http://localhost:9000")
public interface RatingService {

    @GetMapping("/ratingsdata/{managerInput}/{peerInput}/{dept}")
    Double getRating(@PathVariable Double managerInput, @PathVariable Double peerInput,
            @PathVariable String dept);
}
额外优化建议
  • 避免硬编码网关地址:可以将网关注册到Eureka,Feign直接调用网关的服务名API-GATEWAY,替换硬编码的url="http://localhost:9000",提升架构灵活性:
    @FeignClient(name = "API-GATEWAY")
    public interface RatingService {
        // ... 方法不变
    }
    
  • 异步场景处理:如果是异步调用,需要手动传递请求上下文,否则RequestContextHolder会无法获取到当前请求,导致Token无法传递。

内容的提问来源于stack exchange,提问作者Ambrish Mayank

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 09:05:31