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