配置 Fegin 拦截器解决微服务之间需要认证才能访问得问题
项目背景
Spring Cloud 项目,有前端,有后端,后端服务整合了 Cloud Security OAuth2 ,请求后端的服务需要携带认证信息,即请求头中需要携带” Authorization Bearer …“ 的Token 头信息。
后台微服务还存在服务之间采用 Fegin 的调用,在前端请求后端时,是携带 Token,可以正常请求响应的,但是当微服务之间调用时,报:
1 2 3 4
| { "error":"unauthorized", "error_description":"Full authentication is required to access this resource" }
|
调用关系简图:
这是因为微服务之间的调用默认是不携带 令牌 Token 导致的(令牌信息存在 Authorization 请求头中),如果要传递 header 信息,可以采用 Fegin拦截器实现。
Fegin 拦截器
可以在 Common 项目中定义一个 Fegin 拦截器:
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
| @Slf4j public class FeignClientInterceptor implements RequestInterceptor { @Override public void apply(RequestTemplate requestTemplate) { try { ServletRequestAttributes attributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes(); if(attributes!=null){ HttpServletRequest request = attributes.getRequest(); Enumeration<String> headerNames = request.getHeaderNames(); if (headerNames != null) { while (headerNames.hasMoreElements()) { String name = headerNames.nextElement(); String values = request.getHeader(name); if("authorization".equalsIgnoreCase(name)){ requestTemplate.header(name, values); } } } } }catch (Exception e) { log.error("Fegin拦截器异常:",e); } } }
|
回到项目简图,因为 ”微服务1“ 调用 ”微服务2“,所以只要在 ”微服务1“ 中装载该 Fegin 拦截器即可:
1 2 3 4
| @Bean public FeignClientInterceptor feignClientInterceptor(){ return new FeignClientInterceptor(); }
|