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

微信公众号

                          
posted @ 2020-01-13 13:54  盲目的拾荒者  阅读(14628)  评论(1编辑  收藏  举报