Thanks to visit codestin.com
Credit goes to github.com

Skip to content

sa-token-reactor-spring-boot3-starter SaReactorFilter提前清除上下文,导致无法在登录的Controller内调用StpUtil.login();。调用会报错 #885

@ZYX2018

Description

@ZYX2018

使用版本:

<dependency>
            <groupId>cn.dev33</groupId>
            <artifactId>sa-token-reactor-spring-boot3-starter</artifactId>
            <version>1.44.0</version>
        </dependency>

报错信息:

Image Image

2025-12-31 15:00:01.043 [reactor-http-nio-3] INFO c.g.g.e.h.GlobalExceptionHandlerAdvice - [saTokenExceptionHandler,97] - SaTokenException
cn.dev33.satoken.exception.SaTokenContextException: SaTokenContext 上下文尚未初始化
at cn.dev33.satoken.context.SaTokenContextForThreadLocalStaff.getModelBox(SaTokenContextForThreadLocalStaff.java:73)
Suppressed: The stacktrace has been enhanced by Reactor, refer to additional information below:
Assembly trace from producer [reactor.core.publisher.MonoFlatMap] :
reactor.core.publisher.Mono.flatMap(Mono.java:3179)
org.springframework.web.reactive.result.method.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:189)
Error has been observed at the following site(s):
*___Mono.flatMap ⇢ at org.springframework.web.reactive.result.method.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:189)
*_____Mono.defer ⇢ at org.springframework.web.reactive.result.method.annotation.RequestMappingHandlerAdapter.handle(RequestMappingHandlerAdapter.java:283)
*_____Mono.then ⇢ at org.springframework.web.reactive.result.method.annotation.RequestMappingHandlerAdapter.handle(RequestMappingHandlerAdapter.java:283)
|
Mono.doOnNext ⇢ at org.springframework.web.reactive.result.method.annotation.RequestMappingHandlerAdapter.handle(RequestMappingHandlerAdapter.java:284)
Original Stack Trace:
at cn.dev33.satoken.context.SaTokenContextForThreadLocalStaff.getModelBox(SaTokenContextForThreadLocalStaff.java:73)
at cn.dev33.satoken.context.SaTokenContextForThreadLocal.getModelBox(SaTokenContextForThreadLocal.java:55)
at cn.dev33.satoken.context.SaTokenContext.getStorage(SaTokenContext.java:86)
at cn.dev33.satoken.context.SaHolder.getStorage(SaHolder.java:69)
at cn.dev33.satoken.stp.StpLogic.setTokenValueToStorage(StpLogic.java:224)
at cn.dev33.satoken.stp.StpLogic.setTokenValue(StpLogic.java:204)
at cn.dev33.satoken.stp.StpLogic.login(StpLogic.java:464)
at cn.dev33.satoken.stp.StpLogic.login(StpLogic.java:420)
at cn.dev33.satoken.stp.StpUtil.login(StpUtil.java:176)
at com.glodon.gbes.evaluai.controller.user.LoginController.ssoLogin(LoginController.java:184)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
at java.base/java.lang.reflect.Method.invoke(Method.java:580)
at org.springframework.web.reactive.result.method.InvocableHandlerMethod.lambda$invoke$0(InvocableHandlerMethod.java:208)
at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:132)
at reactor.core.publisher.MonoZip$ZipCoordinator.signal(MonoZip.java:297)
at reactor.core.publisher.MonoZip$ZipInner.onNext(MonoZip.java:478)
at reactor.core.publisher.MonoPeekTerminal$MonoTerminalPeekSubscriber.onNext(MonoPeekTerminal.java:180)
at reactor.core.publisher.FluxDefaultIfEmpty$DefaultIfEmptySubscriber.onNext(FluxDefaultIfEmpty.java:122)
at reactor.core.publisher.FluxPeekFuseable$PeekFuseableSubscriber.onNext(FluxPeekFuseable.java:210)
at reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber.onNext(FluxSwitchIfEmpty.java:74)
at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onNext(FluxOnErrorResume.java:79)
at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:158)
at reactor.core.publisher.FluxContextWrite$ContextWriteSubscriber.onNext(FluxContextWrite.java:107)
at reactor.core.publisher.FluxMapFuseable$MapFuseableConditionalSubscriber.onNext(FluxMapFuseable.java:299)
at reactor.core.publisher.FluxFilterFuseable$FilterFuseableConditionalSubscriber.onNext(FluxFilterFuseable.java:337)
at reactor.core.publisher.Operators$BaseFluxToMonoOperator.completePossiblyEmpty(Operators.java:2096)
at reactor.core.publisher.MonoCollect$CollectSubscriber.onComplete(MonoCollect.java:145)
at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onComplete(FluxMapFuseable.java:152)
at reactor.core.publisher.FluxPeekFuseable$PeekFuseableSubscriber.onComplete(FluxPeekFuseable.java:277)
at reactor.core.publisher.FluxMap$MapSubscriber.onComplete(FluxMap.java:144)
at reactor.netty.channel.FluxReceive.onInboundComplete(FluxReceive.java:413)
at reactor.netty.channel.ChannelOperations.onInboundComplete(ChannelOperations.java:464)
at reactor.netty.http.server.HttpServerOperations.handleLastHttpContent(HttpServerOperations.java:903)
问题2:
既然是响应式,就应该遵循reactive 。 SaFilterAuthStrategy 的返回值应当是Mono包装的而不是void 不然我过滤器内只能阻塞执行业务

Image Image 这是不合理的。

希望结果:

完全响应式。且不要提前清除上下文,还没到业务层怎么就可以清除上下文呢。

复现步骤:

< 备注:如果复现步骤比较复杂,请将 demo 上传到 gitee 并留下地址 >

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions