WeBankBlockchain/WeCross

wecross-java-sdk 进行跨链应用开发时,使用容器注入的 WeCrossRPC 登录信息会在10次http请求后消失。

graymagic opened this issue · 3 comments

BUG描述
使用spring boot 进行跨链应用开发,初始化 WeCrossRPC 的初始登陆用户 并 使用依赖注入 交付 spring 容器管理,在http请求十次之后,WeCrossRPC 对象的用户登录信息 被重置。会导致十次后的每一次http请求都需要先登陆一次才能访问 wecross路由的 rpc 端口。

重现方式
重现 BUG 的操作步骤。
1.创建 WeCrossRPC 的初始化类 或者 配置类,并使用 spring 的依赖注入管理对象。
2.将 1 创建的文件中 初始化的 WeCrossRPC 对象 进行login操作,嵌入用户登录信息。
3.根据 sdk 编写接口(除login等用户接口)
4.调用接口11-20此,观察返回结果

预期结果
11次时会出现提示 ”接口调用需要用户登陆“

截图
image
image

环境

  • 操作系统: CentOS
  • 运行库 java8
  • 版本 jdk-1.8.0_372、Centos7.9.2009

首先 wecross-java-sdk 是使用 Spring Security 的 UsernamePasswordAuthenticationToken 存储用户登录信息,采用线程池模式为 InheritableThreadLocal ,此线程池模式可以保证 父线程、子线程相同的 ThreadLocal。
导致的问题:
spring boot 框架 初始化容器时,初始线程池可以设定线程的上下文信息。但是在处理 http 请求时会 从线程池内拿到线程 去处理此请求。结束后,当线程回归线程池时,线程上下文信息会被清除,便导致用户的登陆token丢失。
以此便造成了起初几次http请求是可以通过的,但是后面就会提示无登录信息。

Hi @graymagic ,
感谢提出issue,这里确实会在使用线程池时出现问题。我们在后续版本会考虑更改保存token的方式。初步想法是将存储模式改成global,但会不会有安全风险还有待商榷。

https://github.com/alibaba/transmittable-thread-local
可以参考下这个线程池的源码思路(注意:Spring-Security并不支持这个线程池)
这个方式可以解决线程池清除线程上下文的场景 bug
image