Spring WebFilter未作用于WebClient请求的问题排查
问题原因与解决方案
核心问题:WebFilter的作用范围错误
WebFilter是Spring WebFlux用于拦截服务器接收的入站HTTP请求的组件,根本不会作用于WebClient发起的出站外部请求,这就是你的过滤器代码从未执行的原因。
正确方案:使用ExchangeFilterFunction拦截WebClient出站请求
要给WebClient的请求添加令牌,需要使用专门针对出站请求的ExchangeFilterFunction来实现拦截逻辑。
1. 替换WebFilter为ExchangeFilterFunction
@Component public class Auth0ExchangeFilter { @Value("${auth0.audiences}") private Set<String> auth0Audiences; @Autowired private Auth0Client auth0Client; public ExchangeFilterFunction addAuthToken() { return ExchangeFilterFunction.ofRequestProcessor(clientRequest -> { String audience = clientRequest.url().getHost(); System.out.println("We've reached this piece of code"); if (auth0Audiences.contains(audience)) { String accessToken = auth0Client.getAccessToken(audience); // 构建修改后的请求,添加Authorization头 ClientRequest modifiedRequest = ClientRequest.from(clientRequest) .header("Authorization", "Bearer " + accessToken) .build(); return Mono.just(modifiedRequest); } return Mono.just(clientRequest); }); } }
2. 配置WebClient并绑定过滤器
@Component public class TestAPICall { private final WebClient client; // 通过构造注入过滤器,并初始化带拦截逻辑的WebClient public TestAPICall(Auth0ExchangeFilter auth0ExchangeFilter) { this.client = WebClient.builder() .filter(auth0ExchangeFilter.addAuthToken()) .build(); } @Scheduled(fixedRate = 10000) public void scheduleFixedRateTask() { client.get() .uri("https://google.com") .retrieve() .bodyToMono(String.class) .block(); } }
额外注意点
- 原代码中试图修改
ServerHttpRequest的headers是无效的,因为ServerHttpRequest的header集合是不可变的;而WebClient的ClientRequest需要通过ClientRequest.from()方法构建新的请求对象来修改头部。 - 必须使用
WebClient.builder()创建客户端并绑定过滤器,直接调用WebClient.create()生成的客户端不会应用任何自定义拦截逻辑。
内容的提问来源于stack exchange,提问作者Farhan Islam
相关产品推荐
相关产品推荐

