From 31ba21d0f9394ea50eba028457f072bea834a42c Mon Sep 17 00:00:00 2001 From: theo <971366405@qq.com> Date: Thu, 30 Jul 2026 14:08:53 +0800 Subject: [PATCH] =?UTF-8?q?fix(security):=20=E8=A7=A3=E5=86=B3SSE=E5=BC=82?= =?UTF-8?q?=E6=AD=A5=E8=AF=B7=E6=B1=82=E8=B6=85=E6=97=B6=E5=92=8C=E6=9D=83?= =?UTF-8?q?=E9=99=90=E9=AA=8C=E8=AF=81=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 添加AsyncRequestTimeoutException异常处理器 - 配置ASYNC调度请求直接放行以支持SSE功能 - 允许SSE emitter.send()等异步请求无需Authorization头验证 --- .../youlai/boot/auth/security/config/SecurityConfig.java | 3 +++ .../boot/framework/web/advice/GlobalExceptionHandler.java | 8 ++++++++ 2 files changed, 11 insertions(+) diff --git a/src/main/java/com/youlai/boot/auth/security/config/SecurityConfig.java b/src/main/java/com/youlai/boot/auth/security/config/SecurityConfig.java index 597afd12..818935cb 100644 --- a/src/main/java/com/youlai/boot/auth/security/config/SecurityConfig.java +++ b/src/main/java/com/youlai/boot/auth/security/config/SecurityConfig.java @@ -22,6 +22,7 @@ import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.ProviderManager; import org.springframework.security.authentication.dao.DaoAuthenticationProvider; import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity; +import jakarta.servlet.DispatcherType; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer; @@ -59,6 +60,8 @@ public class SecurityConfig { public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { return http .authorizeHttpRequests(requestMatcherRegistry -> { + // ASYNC 调度请求(如 SSE emitter.send())不经过外部 HTTP 请求,没有 Authorization 头,直接放行 + requestMatcherRegistry.dispatcherTypeMatchers(DispatcherType.ASYNC).permitAll(); String[] ignoreUrls = securityProperties.getIgnoreUrls(); if (ArrayUtil.isNotEmpty(ignoreUrls)) { requestMatcherRegistry.requestMatchers(ignoreUrls).permitAll(); diff --git a/src/main/java/com/youlai/boot/framework/web/advice/GlobalExceptionHandler.java b/src/main/java/com/youlai/boot/framework/web/advice/GlobalExceptionHandler.java index 89c044ec..f4c5b355 100644 --- a/src/main/java/com/youlai/boot/framework/web/advice/GlobalExceptionHandler.java +++ b/src/main/java/com/youlai/boot/framework/web/advice/GlobalExceptionHandler.java @@ -23,6 +23,7 @@ import org.springframework.web.bind.MissingServletRequestParameterException; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestControllerAdvice; +import org.springframework.web.context.request.async.AsyncRequestTimeoutException; import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException; import org.springframework.web.servlet.NoHandlerFoundException; import tools.jackson.core.JacksonException; @@ -174,6 +175,13 @@ public class GlobalExceptionHandler { return Result.failed(e.getMessage()); } + @ExceptionHandler(AsyncRequestTimeoutException.class) + @ResponseStatus(HttpStatus.OK) + public Result handleAsyncRequestTimeoutException(AsyncRequestTimeoutException e) { + log.debug("SSE 异步请求超时"); + return null; + } + @ExceptionHandler(Exception.class) @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) public Result handleException(Exception e) throws Exception {