SpringSecurity和Flux同时使用报未认证问题

问题描述

当在项目中使用SpringSecurity时,如果controller层返回的是flux的流,那么前端请求就会抛出AuthorizationDeniedException异常。

一开始断点调试只是发现AuthorizationFilter过滤器走了两次,第一次正常通过然后springsecurity会清理认证信息导致第二次走过滤器时被判定为未认证于是报错。

一开始在网上看没有有现成的解决方案,但谁知找了五六个都要开会员,于是一怒之下怒了一下,分享出来。

报错原理

正常的springmvc流程应该是:请求-> 过滤器 -> DispatcherServlet -> 执行目标方法 -> 返回->清理SpringSecurity认证缓存

当在servlet中返回flux流式数据时流程大概是这样:请求 -> 过滤器 -> DispatcherServlet -> 执行目标方法 -> 返回flux响应并保存挂起 -> 清理SpringSecurity认证缓存 -> 数据准备好 -> 过滤器 -> DispatcherServlet -> 找到对应挂起的flux往里面塞数据 -> 前端持续接收数据

可以看到问题就出在执行目标方法只是放回流,但是流中数据还没结束。然后往流里塞数据还是得走DispatcherServlet,走servlet就会触发过滤器,就会导致认证异常。

ps: 可能有人会注意到,我的程序明明也有JWT过滤器为啥第二次不重新走JWT过滤器重新认证一遍。原因是过滤器也是有类型的,有的只处理同步请求,有的只处理异步请求,有的都可以处理,其中JWT过滤器是你自己编写的,默认只能处理同步请求,而AuthorizationFilter过滤器同步异步都会处理。

解决办法

方法一

这个方法我觉得是最简单的,就是判断如果是异步请求就不走SpringSecurity的过滤器链(应为SpringSecurity版本不同,所以可能你的配置类的属性和方法可能和我有区别,如果发现爆红,可以去把你的版本发给AI,问下AI该如何配置异步不走SpringSecurity过滤器)

java 复制代码
httpSecurity
        // 核心:忽略异步派发请求(解决二次校验)
        .securityMatcher(serverWebExchange -> {
            // 如果是 异步派发 请求 → 不进入Security过滤器
            boolean isAsync = serverWebExchange.isAsyncStarted()
                    || serverWebExchange.getDispatcherType() ==                 jakarta.servlet.DispatcherType.ASYNC;
            return !isAsync;
        })

我 自己试了一下,一共是不会影响普通方法的认证

方法二

重写AuthorizationFilter过滤器,在其中判断是否是异步请求,然后放行。

PS:如果本文的方法不可以,建议还是将你的版本和问题简单描述给AI,由AI给你答案。应为我在网上也搜了一些,要不然就是要钱要不然就是直接全部放行。

相关推荐
pshdhx_albert3 小时前
AI agent实现打字机效果
java·http·ai编程
沉鱼.443 小时前
第十二届题目
java·前端·算法
建行一世4 小时前
【Windows笔记本大模型“傻瓜式”教程】使用LLaMA-Factory工具来完成对Windows笔记本大模型Qwen2.5-3B-Instruct微调
windows·ai·语言模型·llama
轩轩分享AI4 小时前
DeepSeek、Kimi、笔灵谁最好用?5款网文作者亲测的AI写作神器横评
人工智能·ai·ai写作·小说写作·小说·小说干货
赫瑞4 小时前
数据结构中的排列组合 —— Java实现
java·开发语言·数据结构
哥布林学者5 小时前
深度学习进阶(五)Vision Transformer
机器学习·ai
叹一曲当时只道是寻常5 小时前
Xcode 接入智谱 GLM Coding Plan 报错解决方案
ai·xcode
周末也要写八哥5 小时前
多进程和多线程的特点和区别
java·开发语言·jvm
惜茶6 小时前
vue+SpringBoot(前后端交互)
java·vue.js·spring boot
杰克尼7 小时前
springCloud_day07(MQ高级)
java·spring·spring cloud