OpenFeign客户端问题:多个Basic Authentication令牌被应用到同一请求
解决Feign客户端多Basic Auth授权头问题
问题原因
Spring Cloud Feign会自动收集Spring容器中所有类型为RequestInterceptor的Bean,并将其应用到所有Feign客户端实例中。你定义的两个BasicAuthRequestInterceptor(分别对应app1和app2)都被注册为全局Bean,导致每个Feign客户端的请求都会带上两个Auth头,触发服务端400错误。
解决方案
方法一:通过作用域隔离配置类
给每个Feign配置类添加@Configuration和@Scope("feignClient")注解,确保每个Feign客户端拥有独立的配置实例,拦截器不会跨客户端共享:
AppOneFeignClientConfiguration 修改后
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Scope; import feign.Logger; import feign.auth.BasicAuthRequestInterceptor; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; @Configuration @Scope("feignClient") public class AppOneFeignClientConfiguration { @Bean public BasicAuthRequestInterceptor appOneBasicAuthRequestInterceptor( @Value("${app1_user_name}") String username, @Value("${app1_password}") String password ) { return new BasicAuthRequestInterceptor(username, password); } @Bean Logger.Level appOneFeignLoggerLevel() { return Logger.Level.BASIC; } }
AppTwoFeignClientConfiguration 修改后
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Scope; import feign.Logger; import feign.auth.BasicAuthRequestInterceptor; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; @Configuration @Scope("feignClient") public class AppTwoFeignClientConfiguration { @Bean public BasicAuthRequestInterceptor appTwoBasicAuthRequestInterceptor( @Value("${app2_user_name}") String username, @Value("${app2_password}") String password ) { return new BasicAuthRequestInterceptor(username, password); } @Bean Logger.Level appTwoFeignLoggerLevel() { return Logger.Level.BASIC; } }
方法二:通过Feign.Builder直接配置拦截器
不将BasicAuthRequestInterceptor注册为全局Bean,而是在配置类中构建专属的Feign.Builder,拦截器仅作用于当前客户端:
AppOneFeignClientConfiguration 修改后
import feign.Feign; import feign.Logger; import feign.auth.BasicAuthRequestInterceptor; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; public class AppOneFeignClientConfiguration { @Bean public Feign.Builder feignBuilder(@Value("${app1_user_name}") String username, @Value("${app1_password}") String password) { return Feign.builder() .requestInterceptor(new BasicAuthRequestInterceptor(username, password)) .logLevel(Logger.Level.BASIC); } }
AppTwoFeignClientConfiguration 修改后
import feign.Feign; import feign.Logger; import feign.auth.BasicAuthRequestInterceptor; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; public class AppTwoFeignClientConfiguration { @Bean public Feign.Builder feignBuilder(@Value("${app2_user_name}") String username, @Value("${app2_password}") String password) { return Feign.builder() .requestInterceptor(new BasicAuthRequestInterceptor(username, password)) .logLevel(Logger.Level.BASIC); } }
验证
修改完成后,调用AppOneClient.getName()时只会携带app1的Basic Auth头,调用AppTwoClient.getAddress()时只会携带app2的Auth头,不会再出现头重复的问题。
内容的提问来源于stack exchange,提问作者RohitG
相关产品推荐
相关产品推荐

