解决跨微服务调用token共享问题

news2024/11/18 16:46:09

场景描述

使用jeecg搭建SpringCloud微服务系统模块,各个系统模块单独创建了拦截器进行权限校验。结果发现跨微服务调用存在鉴权失败问题。不能正常跨微服务调用。

原因描述

单个微服务鉴权拦截器。

package org.jeecg.modules.taxation.inerceptor;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * 配置请求拦截器
 */
@Configuration
public class TaxAppInterceptorConfig implements WebMvcConfigurer {

    @Bean
    public TaxAppInterceptor appInterceptor() {
        return new TaxAppInterceptor();
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {

        // 这里的拦截器是new出来的,在Spring框架中可以交给IOC进行依赖注入,直接使用@Autowired注入
        registry.addInterceptor(appInterceptor())
                //授权接口
                .addPathPatterns("/api/tax/**")

                //排除接口
                //用户
                .excludePathPatterns("/api/tax/member/**")
                //申报
                .excludePathPatterns("/api/tax/declare/**")
                //if


                .excludePathPatterns("/wx/callback/alipayCallback");


    }
}

小程序等用户请求,拦截器

/**
 *  小程序等用户请求,拦截器
 */
@Component
public class TaxAppInterceptor implements HandlerInterceptor {
    ... 省略代码
}

解决方案

方案1:更改FeignConfig,添加token传递,jeecg原生jar包,这个修改不了。
方案2:替换FeignConfig,添加token传递, 类冲突,无法替换, allow-circular-references 无效。
方案3:抽取每个服务的拦截器到网关统一验证。如果放行shiroConfig,用网关鉴权,可能存在单jar包,直接访问问题,
所以①不能放行shiroConfig,②更改shiro拦截代码,③添加网关统一校验。
方案4:服务端的filter区分客户端是feign还是前端浏览器,是feign就不鉴权了
方案5:feign能设置全局默认传的参数,可以加一些参数让服务端识别出是feign。

目前为了时间,暂时使用的方案2,构架层面应该使用方案3,统一网关鉴权。

配置FeignClient的configuration解决跨微服务token共享鉴权问题

在这里插入图片描述

调用端声明

package org.jeecg.modules.ccb.api;
import org.jeecg.common.constant.ServiceNameConstants;
import org.jeecg.modules.ccb.api.fallback.CcbHelloFallback;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;

@FeignClient(value = ServiceNameConstants.SERVICE_TAXATION,configuration = FeignHelloConfiguration.class,fallbackFactory = CcbHelloFallback.class)
public interface TaxationApi {

    /**
     * taxation hello 微服务接口
     * @param
     * @return
     */
    @GetMapping(value = "/api/tax/hello")
    String callHello();
}

Feign配置类

重点是:

String token1 = request.getHeader(“token”);
requestTemplate.header(“token”, new String[]{token1});

package org.jeecg.modules.ccb.api;


import com.alibaba.cloud.commons.lang.StringUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import com.alibaba.fastjson.support.springfox.SwaggerJsonSerializer;
import feign.Contract;
import feign.RequestInterceptor;
import feign.codec.Decoder;
import feign.codec.Encoder;
import feign.form.spring.SpringFormEncoder;
import org.jeecg.common.config.TenantContext;
import org.jeecg.common.config.mqtoken.UserTokenContext;
import org.jeecg.common.util.PathMatcherUtil;
import org.jeecg.config.sign.util.HttpUtils;
import org.jeecg.config.sign.util.SignUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
import org.springframework.cloud.openfeign.support.SpringDecoder;
import org.springframework.cloud.openfeign.support.SpringEncoder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.context.annotation.Scope;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.SortedMap;

public class FeignHelloConfiguration {


    private static final Logger log = LoggerFactory.getLogger(FeignHelloConfiguration.class);
    public static final String X_ACCESS_TOKEN = "X-Access-Token";
    public static final String X_SIGN = "X-Sign";
    public static final String X_TIMESTAMP = "X-TIMESTAMP";
    public static final String TENANT_ID = "tenant-id";

    public FeignHelloConfiguration() {
    }

    @Bean
    public RequestInterceptor requestInterceptor() {
        return (requestTemplate) -> {
            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            String token;
            String queryLine;
            String signUrls;
            if (null != attributes) {
                HttpServletRequest request = attributes.getRequest();



                //token传递
                String token1 = request.getHeader("token");
                requestTemplate.header("token", new String[]{token1});



                log.debug("Feign request: {}", request.getRequestURI());
                token = request.getHeader("X-Access-Token");
                if (token == null || "".equals(token)) {
                    token = request.getParameter("token");
                }

                log.info("Feign Login Request token: {}", token);
                requestTemplate.header("X-Access-Token", new String[]{token});
                queryLine = request.getHeader("tenant-id");
                if (queryLine == null || "".equals(queryLine)) {
                    queryLine = request.getParameter("tenant-id");
                }

                log.info("Feign Login Request tenantId: {}", queryLine);
                requestTemplate.header("tenant-id", new String[]{queryLine});
            } else {
                signUrls = UserTokenContext.getToken();
                log.info("Feign no Login token: {}", signUrls);
                requestTemplate.header("X-Access-Token", new String[]{signUrls});
                token = TenantContext.getTenant();
                log.info("Feign no Login tenantId: {}", token);
                requestTemplate.header("tenant-id", new String[]{token});
            }



        };
    }

    @Bean
    feign.Logger.Level feignLoggerLevel() {
        return feign.Logger.Level.FULL;
    }

    @Bean
    @Primary
    @Scope("prototype")
    public Encoder multipartFormEncoder(ObjectFactory<HttpMessageConverters> messageConverters) {
        return new SpringFormEncoder(new SpringEncoder(messageConverters));
    }

    @Bean
    public Encoder feignEncoder() {
        return new SpringEncoder(this.feignHttpMessageConverter());
    }

    @Bean
    public Decoder feignDecoder() {
        return new SpringDecoder(this.feignHttpMessageConverter());
    }

    private ObjectFactory<HttpMessageConverters> feignHttpMessageConverter() {
        HttpMessageConverters httpMessageConverters = new HttpMessageConverters(new HttpMessageConverter[]{this.getFastJsonConverter()});
        return () -> {
            return httpMessageConverters;
        };
    }

    private FastJsonHttpMessageConverter getFastJsonConverter() {
        FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter();
        List<MediaType> supportedMediaTypes = new ArrayList();
        MediaType mediaTypeJson = MediaType.valueOf("application/json");
        supportedMediaTypes.add(mediaTypeJson);
        converter.setSupportedMediaTypes(supportedMediaTypes);
        FastJsonConfig config = new FastJsonConfig();
        config.getSerializeConfig().put(JSON.class, new SwaggerJsonSerializer());
        config.setSerializerFeatures(new SerializerFeature[]{SerializerFeature.DisableCircularReferenceDetect});
        converter.setFastJsonConfig(config);
        return converter;
    }
}

被调用端拦截器

重点是获取刚刚传递过来的token值

request.getHeader(“token”);

/**
 *  小程序等用户请求,拦截器
 */
@Component
public class TaxAppInterceptor implements HandlerInterceptor {

    @Autowired
    private JwtTokenUtil jwtTokenUtil;

    @Value("${jwt.secret}")
    private String jwtSecret;

    /**
     * 查数据库登录验证拦截
     *
     * @param request
     * @param response
     * @param o
     * @return
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object o) throws Exception {
        String requestURI = request.getRequestURI();
        String token = request.getHeader("token");

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/159967.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【MySQL】MySQL单表操作

序号系列文章2【MySQL】MySQL基本操作详解3【MySQL】MySQL基本数据类型4【MySQL】MySQL表的七大约束5【MySQL】字符集与校对集详解文章目录MySQL单表操作1&#xff0c;数据操作1.1&#xff0c;复制表结构和数据1.2&#xff0c;解决主键冲突1.3&#xff0c;清空数据1.4&#xff…

二叉树详解(概念+遍历实现)

一、基本概念 1.最左孩子结点&#xff1a;一个结点的孩子结点中位于最左边的孩子结点。例如&#xff0c;A——B&#xff0c;B——E&#xff1b; 2.树的高度&#xff1a;树的最高层数&#xff1b; 3.路径长度&#xff1a;树中的任意两个顶点之间都存在唯一的一条路径。一条路径所…

我们这样做容器分层性能测试

前言目前闲鱼不少业务正在从H5/Weex升级到Kun&#xff08;基于W3C标准&Flutter打造的混合高性能终端容器&#xff09;&#xff0c;从测试角度来看&#xff0c;我们希望这种升级迭代对于用户体验是正向的&#xff0c;所以用好性能测试这把标准尺就显得格外重要。早期做性能保…

有什么比较好用的低代码开发平台?

国内有特色的低代码快速开发平台产品有哪些&#xff1f;这篇就来介绍下目前市面上主要的几家零代码开发平台&#xff01; 简道云、明道云、IVX这几家目前是无代码赛道的明星选手&#xff0c;在市场综合表现上名列前茅。宜创、红圈营销虽也极具潜力&#xff0c;但在市场表现力上…

Java开发技术之成为高级java工程师必须学习的三个技术

所谓的Java高级程序员往往是经验和能力的结合&#xff0c;并不是说掌握了哪几个技术就是高级程序员了&#xff0c;能否把掌握的知识运用到实际的项目中&#xff0c;并且解决了具体的问题&#xff0c;这个才是衡量一个Java程序员的标准。 那么对于一名Java程序员来说&#xff0…

Java项目:房屋租赁系统设计和实现(java+ssm+mysql+spring+jsp)

源码获取&#xff1a;博客首页 "资源" 里下载&#xff01; 主要功能描述&#xff1a; 1.登录管理&#xff1a;主要有管理员登录和租客登录 2.房源列表以及添加房源功能&#xff1a; 3.租赁合同管理以及在租房源和已退租房源信息管理: 4.看房申请和退租申请管理&a…

【 java 集合】HashMap源码分析

&#x1f4cb; 个人简介 &#x1f496; 作者简介&#xff1a;大家好&#xff0c;我是阿牛&#xff0c;全栈领域优质创作者。&#x1f61c;&#x1f4dd; 个人主页&#xff1a;馆主阿牛&#x1f525;&#x1f389; 支持我&#xff1a;点赞&#x1f44d;收藏⭐️留言&#x1f4d…

python基础篇之列表(增删改查)

大家好&#xff0c;我是csdn的博主&#xff1a;lqj_本人 这是我的个人博客主页&#xff1a;lqj_本人的博客_CSDN博客-微信小程序,前端,vue领域博主lqj_本人擅长微信小程序,前端,vue,等方面的知识https://blog.csdn.net/lbcyllqj?spm1000.2115.3001.5343 哔哩哔哩欢迎关注&…

excel数据统计:三个公式提高统计工作效率

善于在工作中使用函数、公式可以提高工作效率&#xff0c;结合近期学员们遇到的问题&#xff0c;老菜鸟总结了三个非常实用的公式&#xff0c;每个公式都可以解决一类问题。学会这三个公式套路&#xff0c;就能解决日常遇到的很多麻烦事。第一类问题&#xff1a;对指定时间段的…

通过nvm 控制node的常见命令

通过nvm 控制node查看本电脑安装的node版本号切换到对应的node版本号可以查看nvm的全部命令查看node可安装的全部版本号下载对应node的版本查看本电脑安装的node版本号 nvm ls 查看本电脑安装的node版本号 切换到对应的node版本号 nvm use 版本号 切换到对应的node版本号 注意…

基于Python + Django 的密码自助平台项目(完整代码)

场景说明&#xff1a;因为本公司 AD 是早期已经在用&#xff0c;用户的个人信息不是十分全面&#xff0c;例如:用户手机号。 钉钉是后来才开始使用&#xff0c;钉钉默认是使用手机号登录。 用户自行重置密码时如果通过手机号来进行钉钉与 AD 之间的验证就行不通了。逻辑&#x…

Linux驱动开发基础_在设备树中指定中断以及在代码中获得中断

目录 1 设备树里中断节点的语法 1.1 设备树里的中断控制器 1.2 设备树里使用中断 2 设备树里中断节点的示例 3 在代码中获得中断 3.1 对于 platform_device 3.2 对于 I2C 设备、SPI 设备 3.3 调用 of_irq_get 获得中断号 3.4 对于 GPIO 1 设备树里中断节点的语法…

OVN实验----L3互通

概述 物理拓扑 如上一个实验OVN实验----L2互通 逻辑拓扑 按照上个实验OVN实验----L2互通 的操作方式&#xff0c;再配置一组容器blue&#xff0c;网段192.168.2.0/24 配置完成后可以在central上ovn-sbctl show看到如下4个绑定接口 此时&#xff0c;red和blue两个网段内是可…

EasyTrans,一个注解搞定数据翻译,减少30%SQL代码量

介绍easy trans适用于3种场景1 有userId/idCardNo(身份证号码-唯一键场景) 需要 userName&#xff0c;无需联表查询。2 有gender code 0 需要 男。3 枚举指定属性给前端亮点1 缓存支持2 跨微服务翻译支持(User和Order 是2个不同微服务&#xff0c;order里面有userId 需要userNa…

strapi系列--如何自定义非界面化的接口,定制化自己的业务逻辑

为什么要进行后端定制呢&#xff1f; 在实际开发过程中&#xff0c;项目中有些需求是不需要创建界面化接口的&#xff0c;需要我们定制化自己的业务逻辑&#xff0c;那么我们该如何处理这个需求呢&#xff1f;本文以图文并茂的形式&#xff0c;定制一个我们自己的业务逻辑接口…

blender 应用物体变换的作用

编辑模式和物体模式操作的区别 旋转 在物体模式下旋转时物体旋转值会发生变换** 在编辑模式下旋转时物体不会发生变化** 缩放 在物体模式下缩放会导致缩放尺寸发生变化 在编辑模式下缩放时&#xff0c;缩放属性不会发生变化 应用物体变换 把物体模式下的缩放旋转变换应…

Android---TabLayout

目录 TabLayout TabItem ​编辑 演示效果的xml TabLayout TabLayout 在开发中一般作为选项卡使用&#xff0c;常与 ViewPager2 和 Fragment 结合起来使用。 常用属性&#xff1a; app:tabBackground 设置 TabLayout 的背景色&#xff0c;改变整个TabLayout 的颜色&#xf…

绪论的习题

刘佳瑜*&#xff0c;王越 *, 黄扬* , 张钊* (淮北师范大学计算机科学与技术学院&#xff0c;安徽 淮北) *These authors contributed to the work equllly and should be regarded as co-first authors. &#x1f31e;欢迎来到机器学习的世界 &#x1f308;博客主页&#xff1…

idea调试常用的快捷键

一、F7 步入调试&#xff0c;进入当前函数内部。 说明&#xff1a; 如果步入的是自己编的函数&#xff0c;可读性会好很多。 如果是系统函数&#xff0c;我个人目前水平&#xff0c;觉得很难读。而且idea系统已编写好的函数&#xff0c;除非是研究源码&#xff0c;否则感觉…

javaweb08 javaweb、tomcat、maven简介、servlet原理和实例、Mapping映射、请求转发和读取properties文件

文章目录一、javaweb简介二、Tomcat三、Maven四、Servlet简介和HelloWorld五、Servlet原理六、Mapping映射七、ServletContext八、请求转发九、读取资源文件properties一、javaweb简介 在java中&#xff0c;动态web资源开发的技术成为javaweb 人们访问到的任何一个网页和资源…