HTTP Status 401 - Full authentication is required to access this resource


Postman发请求
网关------》A服务    携带JWT做认证ok
网关------》B服务    携带JWT做认证OK,
网关------》A服务----Feign(调用)-----》B服务  Full authentication is required to access this resource


分析:
a.因为Feign在服务之间相互调用如果需要认证,需要实现RequestInterceptor,在每次请求的时候header里面增加(token、oauthToken、Authorization),但是发现单单给header里面增加(token、oauthToken、Authorization),还是会报认证错误。于是把A服务请求中所有header放入RequestInterceptor实现代码中就ok了。

之前的拦截器代码:

import feign.RequestInterceptor; import feign.RequestTemplate; import org.springframework.stereotype.Component; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import javax.servlet.http.HttpServletRequest; import java.util.Enumeration; import java.util.LinkedHashMap; import java.util.Map; /** * Feign统一Token拦截器 */ @Component public class FeignTokenInterceptor implements RequestInterceptor { @Override public void apply(RequestTemplate requestTemplate) { if(null==getHttpServletRequest()){ //此处省略日志记录 return; } //将获取Token对应的值往下面传 requestTemplate.header("Authorization", getHeaders(getHttpServletRequest()).get("Authorization")); } private HttpServletRequest getHttpServletRequest() { try { return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); } catch (Exception e) { return null; } } /** * Feign拦截器拦截请求获取Token对应的值 * @param request * @return */ private Map<String, String> getHeaders(HttpServletRequest request) { Map<String, String> map = new LinkedHashMap<>(); Enumeration<String> enumeration = request.getHeaderNames(); while (enumeration.hasMoreElements()) { String key = enumeration.nextElement(); String value = request.getHeader(key); map.put(key, value); } return map; } }

改动后代码:

import feign.RequestInterceptor; import feign.RequestTemplate; import org.springframework.stereotype.Component; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import javax.servlet.http.HttpServletRequest; import java.util.Enumeration; import java.util.LinkedHashMap; import java.util.Map; import java.util.Map.Entry; import java.util.Set; /** * Feign统一Token拦截器 */ @SuppressWarnings("Duplicates") @Component public class FeignTokenInterceptor implements RequestInterceptor { @Override public void apply(RequestTemplate requestTemplate) { if (null == getHttpServletRequest()) { // 此处省略日志记录 return; } // 将获取Token对应的值往下面传 Map<String, String> headersMap = getHeaders(getHttpServletRequest()); if (headersMap != null && headersMap.size() > 0) { Set<Entry<String, String>> entrySet = headersMap.entrySet(); for (Entry<String, String> entry : entrySet) { String key = entry.getKey(); String value = entry.getValue(); // Authorization //headersMap.get("Authorization") requestTemplate.header(key, value); } } } private HttpServletRequest getHttpServletRequest() { try { return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); } catch (Exception e) { return null; } } /** * Feign拦截器拦截请求获取Token对应的值 * * @param request * @return */ private Map<String, String> getHeaders(HttpServletRequest request) { Map<String, String> map = new LinkedHashMap<>(); Enumeration<String> enumeration = request.getHeaderNames(); while (enumeration.hasMoreElements()) { String key = enumeration.nextElement(); String value = request.getHeader(key); map.put(key, value); } return map; } }


b.线程隔离策略设置为信号量,默认线程
hystrix.command.default.execution.isolation.strategy=SEMAPHORE

官方文档:
如果你需要在你的程序中使用ThreadLocal绑定变量,您需要将Hystrix的线程隔离策略设置为“信号量”或在Fegin中禁用Hystrix
# To disable Hystrix in Feign(禁用断路器,这样将不会走服务降级,之前想调用放返回调用失败异常)
feign.hystrix.enabled=false
# To set thread isolation to SEMAP(设置线程隔离策略为信号量)
hystrix.command.default.execution.isolation.strategy=SEMAPHORE

微信公众号

                          


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM