Feign发起远程调用报错401,使用Spring Cloud Feign实现JWT令牌中继,传递认证信息

在构建微系统的时候,系统由一个微服务A,一个微服务B构成,登录使用的是springsecurity+jwt进行认证,现在登录写在服务A中,在调用服务B时候,报错401了。

test接口为服务A中的调用服务B的接口,在登录状态下,调用test接口,报错401了
在这里插入图片描述
单独调用服务B的接口,没有问题
在这里插入图片描述

先贴原因:
原因:Feign发起远程调用与微服务A调用Feign去发起请求的线程不一样,微服务A调用feign的时候是线程1,通过Feign远程调用微服务B的是feign对象,Feign对象的底层是使用restTemplate对象去调用微服务B,和线程1的request对象没有关系,所以restTemplate对象不含token,没有token就相当于没有用户名和密码,所以就出现401异常。

解决方法:
解决方法:需要使用一个拦截器组件,将request对象中的请求头放到restTemplate对象里,再进行远程调用,就不会出现401异常
拦截器组件的作用:微服务的所有Feign调用在发起HTTP请求之前,先进入这个拦截器。然后再发起调用

在服务A中定义拦截器Interceptor:

@Component
public class Interceptor implements RequestInterceptor {

    /**
     * 拦截器方法
     *
     * @param requestTemplate
     */
    @Override
    public void apply(RequestTemplate requestTemplate) {
        /*
         * 获取原线程的request对象的请求头中的token
         * RequestContextHolder.getRequestAttributes():获取request原始的请求头对象
         * 接口类RequestAttributes不能使用,所以强转为ServletRequestAttributes类型
         */
        ServletRequestAttributes servletRequestAttributes =
                (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        //防止空指针
        if (servletRequestAttributes==null) {
            return;
        }
        //获取原Request对象
        HttpServletRequest request = servletRequestAttributes.getRequest();
        //把原request的请求头的所有参数都拿出来
        Enumeration<String> headerNames = request.getHeaderNames();
        while (headerNames.hasMoreElements()) {
            //获取每个请求头参数的名字
            String name = headerNames.nextElement();
            //获取值
            String value = request.getHeader(name);
            //放到feign调用对象的request中去
            requestTemplate.header(name,value);
        }
    }
}

重启服务,在A中调用B:成功调用到了
在这里插入图片描述
参考链接:
Feign发起远程调用出现401异常(没有访问权限)

Spring Cloud Feign如何实现JWT令牌中继,传递认证信息?

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值