场景
A服务
与B服务
都注册到nacos中,A服务由于业务功能调用B服务的功能,因此A服务会远程调用B服务
。
而此处B服务(系统)采用了SpringSecurity 做了认证
,因此A服务需要在Fegin调用B服务前需要获取认证令牌(Token)
解决方案
A服务配置一个拦截器,当使用Fegin调用前,需要在请求头上加上Token(获取Token方式采用HttpClient)

配置
下面为A服务(系统)需要添加的配置:
Feign 客户端
1 2 3 4 5 6 7 8
| @FeignClient(name = "b-service-name") public interface OrderFeignService {
@GetMapping("/api/orderInfos") List<orderInfoVO> getOrderInfos();
}
|
过滤器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| @Component @Log4j2 public class FeignAuthInterceptor implements RequestInterceptor { private String BSERVICE_GET_TOKEN_URL = "http://b系统ip地址:6666/api/v1/sys/getToken";
@Override public void apply(RequestTemplate requestTemplate) { String token = getCentralUploadToken(); log.info("\n ======== 执行了FeignAuthInterceptor {} ==========\n", token); requestTemplate.header("Authorization", token); }
private String getCentralUploadToken() { String bserviceUserName = "admin"; BServiceUserDTO bServiceUserDTO = new BServiceUserDTO( bserviceUserName, CryptoUtils.encrypt("admin") ); BServiceLoginVO loginVO = null; try { String result = HttpUtils.httpPost(BSERVICE_GET_TOKEN_URL, bServiceUserDTO); log.info("\n ======== result {} ==========\n", result); ObjectMapper objectMapper = new ObjectMapper(); JsonNode body = objectMapper.readTree(result); log.info("\n ======== body {} ==========\n", body); loginVO = objectMapper.treeToValue(body, BServiceLoginVO.class); } catch (Exception e) { e.printStackTrace(); } String token = ""; log.info("\n ======== loginVO {} ==========\n", loginVO); if (null != loginVO) { token = loginVO.getToken(); } System.out.println("token :" + token); return token; }
|
启动类
1 2 3 4 5 6 7 8 9 10 11
| @EnableDiscoveryClient @SpringBootApplication @EnableJpaAuditing @EntityScan(basePackages = "com.aservice.model") @EnableFeignClients @EnableAsync public class AServiceApplication { public static void main(String[] args) { SpringApplication.run(AServiceApplication.class, args); } }
|
单元测试类
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| @RunWith(SpringRunner.class) @SpringBootTest public class TestFeignAuth {
@Autowired private OrderFeignService orderFeignService;
@Test public void testFeignAuth() { List<orderInfoVO> orderInfoVOs = orderFeignService.getOrderInfos(); System.out.println("orderInfoVOs :" + orderInfoVOs); } }
|
注意
上面的B系统中的类,A系统中也需要增加如:orderInfoVO,BServiceLoginVO,CryptoUtils等
测试
启动测试类,如果没有报认证相关的问题,能正常返回结果,都是表明可以
优化
将敏感api_url 信息放到nacos的 yaml 中读取,使得信息更加安全