• HTTP Status 401


    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

    微信公众号

                              
  • 相关阅读:
    C#.NET 大型企业信息化系统集成快速开发平台 4.2 版本
    C#.NET 大型企业信息化系统集成快速开发平台 4.2 版本
    C#.NET 大型企业信息化系统集成快速开发平台 4.2 版本
    C#.NET 大型企业信息化系统集成快速开发平台 4.2 版本
    C#.NET 大型企业信息化系统集成快速开发平台 4.2 版本
    C# ASP.NET 优化程序性能、降低内存使用、提高程序运行速度
    C#.NET 大型企业信息化系统集成快速开发平台 4.2 版本
    C#.NET 大型企业信息化系统集成快速开发平台 4.2 版本
    几十套业务系统集中统一授权管理、几十万账户同步多系统实现经验分享
    C#.NET 大型企业信息化系统集成快速开发平台 4.2 版本
  • 原文地址:https://www.cnblogs.com/niugang0920/p/12186933.html
Copyright © 2020-2023  润新知